aboutsummaryrefslogtreecommitdiff
path: root/gas
diff options
context:
space:
mode:
authorSteve Chamberlain <sac@cygnus>1992-02-22 20:45:24 +0000
committerSteve Chamberlain <sac@cygnus>1992-02-22 20:45:24 +0000
commitc593cf412bc4c50671ae1990c36be0a72eac2e37 (patch)
treef8e1170a1cea5e5b2c27cb017d3be1958cbe0e48 /gas
parent3b548344d0c68e3c66965f10a882112cd6b3bc3c (diff)
downloadgdb-c593cf412bc4c50671ae1990c36be0a72eac2e37.zip
gdb-c593cf412bc4c50671ae1990c36be0a72eac2e37.tar.gz
gdb-c593cf412bc4c50671ae1990c36be0a72eac2e37.tar.bz2
* app.c: MRI compatibility - allow single quote to start a string.
* as.c: fix typo recently introduced. * as.h : Don't include aout/reloc.h - it's not right for COFF! * expr.c: Much rewriting, to accomodate MRI syntax for expressions. Also easier to read now. * listing.c: Put back defuns * read.c: modified to accept MRI syntax, put back listing pseudo ops so that an assembler built with NO_LISTING ignores list ops rather than pukes. * write.c, write.h: fixs - only keep a reloc type in a fix if the target machine is a SPARC or a 29K. * config/obj-aout.c: added s_sect pseudo op * config/obj-coffbfd.c: lints, set the filehdr flags right and fill in the timestamp. * config/obj-coffbfd.h: Since we don't include aout/reloc.h anymore, define all the relocs which the tc-<x> bit will use so we can translate from them to the coff types. * config/tc-a29k.c: reloc_type isn't ane enum any more * config/tc-m68k.c: Added NO_RELOC definition. Now compiles for sparc aout, 68k aout (MRI and MIT syntax), 29k coff. So far works as replacement for sparc and 68k /bin/as.
Diffstat (limited to 'gas')
-rw-r--r--gas/.Sanitize31
-rw-r--r--gas/ChangeLog25
-rw-r--r--gas/as.h9
-rw-r--r--gas/config/obj-coffbfd.c3052
-rw-r--r--gas/config/obj-coffbfd.h14
-rw-r--r--gas/config/tc-a29k.c9
-rw-r--r--gas/config/tc-a29k.h56
-rw-r--r--gas/expr.c1251
-rw-r--r--gas/listing.c1518
-rw-r--r--gas/write.c89
-rw-r--r--gas/write.h62
11 files changed, 3231 insertions, 2885 deletions
diff --git a/gas/.Sanitize b/gas/.Sanitize
index bc93a48..ea72128 100644
--- a/gas/.Sanitize
+++ b/gas/.Sanitize
@@ -30,6 +30,7 @@ Things-to-keep:
.gdbinit
COPYING
ChangeLog
+Makefile.bat
Makefile.in
NOTES
NOTES.config
@@ -51,7 +52,7 @@ bignum-copy.c
bignum.h
cond.c
config
-configdos.bat
+configure.bat
configure.in
debug.c
doc
@@ -105,7 +106,33 @@ echo Done in `pwd`.
#
#
# $Log$
-# Revision 1.9 1992/02/17 15:52:52 rich
+# Revision 1.10 1992/02/22 20:44:46 sac
+# * app.c: MRI compatibility - allow single quote to start a string.
+# * as.c: fix typo recently introduced.
+# * as.h : Don't include aout/reloc.h - it's not right for COFF!
+# * expr.c: Much rewriting, to accomodate MRI syntax for
+# expressions. Also easier to read now.
+# * listing.c: Put back defuns
+# * read.c: modified to accept MRI syntax, put back listing pseudo
+# ops so that an assembler built with NO_LISTING ignores list ops
+# rather than pukes.
+# * write.c, write.h: fixs - only keep a reloc type in a fix if the target
+# machine is a SPARC or a 29K.
+# * config/obj-aout.c: added s_sect pseudo op
+# * config/obj-coffbfd.c: lints, set the filehdr flags right and
+# fill in the timestamp.
+# * config/obj-coffbfd.h: Since we don't include aout/reloc.h
+# anymore, define all the relocs which the tc-<x> bit will use so we
+# can translate from them to the coff types.
+# * config/tc-a29k.c: reloc_type isn't ane enum any more
+# * config/tc-m68k.c: Added NO_RELOC definition.
+#
+# Now compiles for sparc aout, 68k aout (MRI and MIT syntax),
+# 29k coff.
+#
+# So far works as replacement for sparc and 68k /bin/as.
+#
+# Revision 1.9 1992/02/17 15:52:52 rich
# fighting bitrot in a major way
#
# Revision 1.8 1992/02/14 00:21:34 pesch
diff --git a/gas/ChangeLog b/gas/ChangeLog
index 9581934..08a5a89 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,5 +1,30 @@
+Sat Feb 22 12:26:28 1992 Steve Chamberlain (sac at rtl.cygnus.com)
+
+ * app.c: MRI compatibility - allow single quote to start a string.
+ * as.c: fix typo recently introduced.
+ * as.h : Don't include aout/reloc.h - it's not right for COFF!
+ * expr.c: Much rewriting, to accomodate MRI syntax for
+ expressions. Also easier to read now.
+ * listing.c: Put back defuns
+ * read.c: modified to accept MRI syntax, put back listing pseudo
+ ops so that an assembler built with NO_LISTING ignores list ops
+ rather than pukes.
+ * write.c, write.h: fixs - only keep a reloc type in a fix if the target
+ machine is a SPARC or a 29K.
+ * config/obj-aout.c: added s_sect pseudo op
+ * config/obj-coffbfd.c: lints, set the filehdr flags right and
+ fill in the timestamp.
+ * config/obj-coffbfd.h: Since we don't include aout/reloc.h
+ anymore, define all the relocs which the tc-<x> bit will use so we
+ can translate from them to the coff types.
+ * config/tc-a29k.c: reloc_type isn't ane enum any more
+ * config/tc-m68k.c: Added NO_RELOC definition.
+
Fri Feb 21 06:21:07 1992 K. Richard Pixley (rich@rtl.cygnus.com)
+ * Makefile.in: put header files before C source for TAGS; remove
+ references to non-existent syscalls.h.
+
* read.c, write.c subsegs.c: back out the .bss changes.
Fri Feb 21 01:08:48 1992 Minh Tran-Le (TRANLE@INTELLICORP.COM)
diff --git a/gas/as.h b/gas/as.h
index 12aeecb..ca65a0b 100644
--- a/gas/as.h
+++ b/gas/as.h
@@ -65,7 +65,7 @@
#include <stdio.h>
#include <assert.h>
-#include "listing.h"
+
#define obstack_chunk_alloc xmalloc
#define obstack_chunk_free xfree
@@ -263,7 +263,7 @@ struct frag /* a code fragment */
typedef struct frag fragS;
-COMMON fragS * frag_now; /* -> current frag we are building. */
+COMMON fragS *frag_now; /* -> current frag we are building. */
/* This frag is incomplete. */
/* It is, however, included in frchain_now. */
/* Frag_now->fr_fix is bogus. Use: */
@@ -389,7 +389,8 @@ void subsegs_begin();
/* these define types needed by the interfaces */
#include "struc-symbol.h"
-#include "aout/reloc.h"
+/*#include "aout/reloc.h"*/
+
#include "write.h"
#include "expr.h"
#include "frags.h"
@@ -400,6 +401,8 @@ void subsegs_begin();
#include "tc.h"
#include "obj.h"
+#include "listing.h"
+
/*
* Local Variables:
* comment-column: 0
diff --git a/gas/config/obj-coffbfd.c b/gas/config/obj-coffbfd.c
index 4d10635..3936ebf 100644
--- a/gas/config/obj-coffbfd.c
+++ b/gas/config/obj-coffbfd.c
@@ -1,40 +1,40 @@
/* coff object file format with bfd
- Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc.
-
- This file is part of GAS.
-
- GAS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- GAS is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- 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. */
+ Copyright (C) 1989, 1990, 1991 Free Software Foundation, Inc.
+
+This file is part of GAS.
+
+GAS is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GAS is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+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. */
/*
-
- How does this releate to the rest of GAS ?
-
- Well, all the other files in gas are more or less a black box. It
- takes care of opening files, parsing command lines, stripping blanks
- etc etc. This module gets a chance to register what it wants to do by
- saying that it is interested in various pseduo ops. The other big
- change is write_object_file. This runs through all the data
- structures that gas builds, and outputs the file in the format of our
- choice.
-
- Hacked for BFDness by steve chamberlain
-
- This object module now supports the Hitachi H8/300 and the AMD 29k
-
- sac@cygnus.com
- */
+
+ How does this releate to the rest of GAS ?
+
+ Well, all the other files in gas are more or less a black box. It
+ takes care of opening files, parsing command lines, stripping blanks
+ etc etc. This module gets a chance to register what it wants to do by
+ saying that it is interested in various pseduo ops. The other big
+ change is write_object_file. This runs through all the data
+ structures that gas builds, and outputs the file in the format of our
+ choice.
+
+ Hacked for BFDness by steve chamberlain
+
+ This object module now supports the Hitachi H8/300 and the AMD 29k
+
+ sac@cygnus.com
+*/
#include "as.h"
#include "obstack.h"
@@ -45,7 +45,7 @@
/* This vector is used to turn an internal segment into a section #
suitable for insertion into a coff symbol table
- */
+ */
const short seg_N_TYPE[] = { /* in: segT out: N_TYPE bits */
C_ABS_SECTION,
@@ -75,18 +75,15 @@ const short seg_N_TYPE[] = { /* in: segT out: N_TYPE bits */
int function_lineoff = -1; /* Offset in line#s where the last function
started (the odd entry for line #0) */
-int our_lineno_number = 0; /* we use this to build pointers from .bf's
- into the linetable. It should match
- exactly the values that are later
- assigned in text_lineno_number by
- write.c. */
-int text_lineno_number = 0;
+int had_lineno = 0;
+int had_reloc = 0;
+static symbolS*last_line_symbol;
/* Add 4 to the real value to get the index and compensate the
negatives. This vector is used by S_GET_SEGMENT to turn a coff
section number into a segment number
- */
+*/
static symbolS *previous_file_symbol = NULL;
void c_symbol_merge();
static int line_base;
@@ -97,7 +94,7 @@ void EXFUN(bfd_as_write_hook,(struct internal_filehdr *,
bfd *abfd));
static void EXFUN(fixup_segment,(fixS * fixP,
- segT this_segment_type));
+ segT this_segment_type));
static void EXFUN(fill_section,(bfd *abfd ,
struct internal_filehdr *f, unsigned
@@ -110,11 +107,11 @@ static symbolS* EXFUN(tag_find,(char *name));
static int
- EXFUN(c_line_new,(
- symbolS *symbol,
- long paddr,
- unsigned short line_number,
- fragS* frag));
+EXFUN(c_line_new,(
+ symbolS *symbol,
+ long paddr,
+ unsigned short line_number,
+ fragS* frag));
static void EXFUN(w_symbols,
@@ -169,84 +166,84 @@ const pseudo_typeS obj_pseudo_table[] = {
/* Section stuff
-
+
We allow more than just the standard 3 sections, infact, we allow
10 sections, (though the usual three have to be there).
-
+
This structure performs the mappings for us:
-
- */
+
+*/
/* OBS stuff
- static struct internal_scnhdr bss_section_header;
- struct internal_scnhdr data_section_header;
- struct internal_scnhdr text_section_header;
-
- const segT N_TYPE_seg [32] =
- {
-
- };
-
- */
+static struct internal_scnhdr bss_section_header;
+struct internal_scnhdr data_section_header;
+struct internal_scnhdr text_section_header;
+
+const segT N_TYPE_seg [32] =
+{
+
+};
+
+*/
#define N_SEG 32
typedef struct
{
- segT seg_t;
- int i;
+ segT seg_t;
+int i;
} seg_info_type;
seg_info_type seg_info_off_by_4[N_SEG] =
{
- {SEG_PTV, },
- {SEG_NTV, },
- {SEG_DEBUG, },
- {SEG_ABSOLUTE, },
- {SEG_UNKNOWN, },
- {SEG_E0},
- {SEG_E1},
- {SEG_E2},
- {SEG_E3},
- {SEG_E4},
- {SEG_E5},
- {SEG_E6},
- {SEG_E7},
- {SEG_E8},
- {SEG_E9},
- {15},
- {16},
- {17},
- {18},
- {19},
- {20},
- {0},
- {0},
- {0},
- {SEG_REGISTER},0,0,0,0};
+{SEG_PTV, },
+{SEG_NTV, },
+{SEG_DEBUG, },
+{SEG_ABSOLUTE, },
+{SEG_UNKNOWN, },
+{SEG_E0},
+{SEG_E1},
+{SEG_E2},
+{SEG_E3},
+{SEG_E4},
+{SEG_E5},
+{SEG_E6},
+{SEG_E7},
+{SEG_E8},
+{SEG_E9},
+{15},
+{16},
+{17},
+{18},
+{19},
+{20},
+{0},
+{0},
+{0},
+{SEG_REGISTER},0,0,0,0};
#define SEG_INFO_FROM_SECTION_NUMBER(x) (seg_info_off_by_4[(x)+4])
#define SEG_INFO_FROM_SEG_NUMBER(x) (seg_info_off_by_4[(x)])
-relax_addressT
- DEFUN(relax_align,(address, alignment),
- register relax_addressT address AND
- register long alignment )
+ relax_addressT
+DEFUN(relax_align,(address, alignment),
+register relax_addressT address AND
+register long alignment )
{
- relax_addressT mask;
- relax_addressT new_address;
-
- mask = ~ ( (~0) << alignment );
- new_address = (address + mask) & (~ mask);
- return (new_address - address);
+ relax_addressT mask;
+ relax_addressT new_address;
+
+ mask = ~ ( (~0) << alignment );
+ new_address = (address + mask) & (~ mask);
+ return (new_address - address);
} /* relax_align() */
segT
- DEFUN(s_get_segment,(x) ,
- symbolS* x)
+DEFUN(s_get_segment,(x) ,
+symbolS* x)
{
- return SEG_INFO_FROM_SECTION_NUMBER(x->sy_symbol.ost_entry.n_scnum).seg_t;
+ return SEG_INFO_FROM_SECTION_NUMBER(x->sy_symbol.ost_entry.n_scnum).seg_t;
}
@@ -254,61 +251,61 @@ segT
/* calculate the size of the frag chain and fill in the section header
to contain all of it, also fill in the addr of the sections */
static unsigned int DEFUN(size_section,(abfd, idx),
- bfd *abfd AND
- unsigned int idx)
+ bfd *abfd AND
+ unsigned int idx)
{
-
- unsigned int size = 0;
- fragS *frag = segment_info[idx].frchainP->frch_root;
- while (frag) {
- if (frag->fr_address != size) {
- printf("Out of step\n");
- size = frag->fr_address;
- }
- size += frag->fr_fix;
- switch (frag->fr_type) {
- case rs_fill:
- case rs_org:
- size += frag->fr_offset * frag->fr_var;
- break;
- case rs_align:
- size += relax_align(size, frag->fr_offset);
- }
- frag = frag->fr_next;
+
+ unsigned int size = 0;
+ fragS *frag = segment_info[idx].frchainP->frch_root;
+ while (frag) {
+ if (frag->fr_address != size) {
+ printf("Out of step\n");
+ size = frag->fr_address;
+ }
+ size += frag->fr_fix;
+ switch (frag->fr_type) {
+ case rs_fill:
+ case rs_org:
+ size += frag->fr_offset * frag->fr_var;
+ break;
+ case rs_align:
+ size += relax_align(size, frag->fr_offset);
}
- segment_info[idx].scnhdr.s_size = size;
- return size;
+ frag = frag->fr_next;
+ }
+ segment_info[idx].scnhdr.s_size = size;
+ return size;
}
static unsigned int DEFUN(count_entries_in_chain,(idx),
unsigned int idx)
{
- unsigned int nrelocs;
- fixS *fixup_ptr;
-
- /* Count the relocations */
- fixup_ptr = segment_info[idx].fix_root;
- nrelocs = 0;
- while (fixup_ptr != (fixS *)NULL)
- {
- if (TC_COUNT_RELOC(fixup_ptr))
- {
-
+ unsigned int nrelocs;
+ fixS *fixup_ptr;
+
+ /* Count the relocations */
+ fixup_ptr = segment_info[idx].fix_root;
+ nrelocs = 0;
+ while (fixup_ptr != (fixS *)NULL)
+ {
+ if (TC_COUNT_RELOC(fixup_ptr))
+ {
+
#ifdef TC_A29K
-
- if (fixup_ptr->fx_r_type == RELOC_CONSTH)
- nrelocs+=2;
- else
- nrelocs++;
+
+ if (fixup_ptr->fx_r_type == RELOC_CONSTH)
+ nrelocs+=2;
+ else
+ nrelocs++;
#else
- nrelocs++;
+ nrelocs++;
#endif
- }
-
- fixup_ptr = fixup_ptr->fx_next;
- }
- return nrelocs;
+ }
+
+ fixup_ptr = fixup_ptr->fx_next;
+ }
+ return nrelocs;
}
/* output all the relocations for a section */
@@ -316,192 +313,208 @@ void DEFUN(do_relocs_for,(abfd, file_cursor),
bfd *abfd AND
unsigned long *file_cursor)
{
- unsigned int nrelocs;
- unsigned int idx;
-
- for (idx = SEG_E0; idx < SEG_E9; idx++)
- {
- if (segment_info[idx].scnhdr.s_name[0])
- {
-
- struct external_reloc *ext_ptr;
- struct external_reloc *external_reloc_vec;
- unsigned int external_reloc_size;
- unsigned int count = 0;
- unsigned int base = segment_info[idx].scnhdr.s_paddr;
- fixS * fix_ptr = segment_info[idx].fix_root;
- nrelocs = count_entries_in_chain(idx);
- external_reloc_size = nrelocs * RELSZ;
- external_reloc_vec =
- (struct external_reloc*)malloc(external_reloc_size);
-
-
-
- ext_ptr = external_reloc_vec;
-
- /* Fill in the internal coff style reloc struct from the
- internal fix list */
- while (fix_ptr)
- {
- symbolS *symbol_ptr;
- struct internal_reloc intr;
-
- /* Only output some of the relocations */
- if (TC_COUNT_RELOC(fix_ptr))
- {
+ unsigned int nrelocs;
+ unsigned int idx;
+
+ for (idx = SEG_E0; idx < SEG_E9; idx++)
+ {
+ if (segment_info[idx].scnhdr.s_name[0])
+ {
+
+ struct external_reloc *ext_ptr;
+ struct external_reloc *external_reloc_vec;
+ unsigned int external_reloc_size;
+ unsigned int count = 0;
+ unsigned int base = segment_info[idx].scnhdr.s_paddr;
+ fixS * fix_ptr = segment_info[idx].fix_root;
+ nrelocs = count_entries_in_chain(idx);
+
+ if (nrelocs)
+ had_reloc = 1;
+
+ external_reloc_size = nrelocs * RELSZ;
+ external_reloc_vec =
+ (struct external_reloc*)malloc(external_reloc_size);
+
+
+
+ ext_ptr = external_reloc_vec;
+
+ /* Fill in the internal coff style reloc struct from the
+ internal fix list */
+ while (fix_ptr)
+ {
+ symbolS *symbol_ptr;
+ struct internal_reloc intr;
+
+ /* Only output some of the relocations */
+ if (TC_COUNT_RELOC(fix_ptr))
+ {
#ifdef TC_RELOC_MANGLE
- TC_RELOC_MANGLE(fix_ptr, &intr, base);
-
+ TC_RELOC_MANGLE(fix_ptr, &intr, base);
+
#else
- symbolS *dot;
- symbol_ptr = fix_ptr->fx_addsy;
-
- intr.r_type = TC_COFF_FIX2RTYPE(fix_ptr);
- intr.r_vaddr =
- base + fix_ptr->fx_frag->fr_address + fix_ptr->fx_where ;
-
- intr.r_offset = fix_ptr->fx_offset;
-
- intr.r_offset = 0;
-
- /* Turn the segment of the symbol into an offset
- */
- if (symbol_ptr)
- {
- dot = segment_info[S_GET_SEGMENT(symbol_ptr)].dot;
- if (dot)
- {
- intr.r_symndx = dot->sy_number;
- }
- else
- {
- intr.r_symndx = symbol_ptr->sy_number;
- }
-
- }
- else
- {
- intr.r_symndx = -1;
-
-
- }
+ symbolS *dot;
+ symbol_ptr = fix_ptr->fx_addsy;
+
+ intr.r_type = TC_COFF_FIX2RTYPE(fix_ptr);
+ intr.r_vaddr =
+ base + fix_ptr->fx_frag->fr_address + fix_ptr->fx_where ;
+
+ intr.r_offset = fix_ptr->fx_offset;
+
+ intr.r_offset = 0;
+
+ /* Turn the segment of the symbol into an offset
+ */
+ if (symbol_ptr)
+ {
+ dot = segment_info[S_GET_SEGMENT(symbol_ptr)].dot;
+ if (dot)
+ {
+ intr.r_symndx = dot->sy_number;
+ }
+ else
+ {
+ intr.r_symndx = symbol_ptr->sy_number;
+ }
+
+ }
+ else
+ {
+ intr.r_symndx = -1;
+
+
+ }
#endif
-
- (void)bfd_coff_swap_reloc_out(abfd, &intr, ext_ptr);
- ext_ptr++;
-
+
+ (void)bfd_coff_swap_reloc_out(abfd, &intr, ext_ptr);
+ ext_ptr++;
+
#if defined(TC_A29K)
- /* The 29k has a special kludge for the high 16 bit reloc.
- Two relocations are emmited, R_IHIHALF, and
- R_IHCONST. The second one doesn't contain a symbol,
- but uses the value for offset */
-
- if (intr.r_type == R_IHIHALF)
- {
- /* now emit the second bit */
- intr.r_type = R_IHCONST;
- intr.r_symndx = fix_ptr->fx_addnumber;
- (void)bfd_coff_swap_reloc_out(abfd,&intr,ext_ptr);
- ext_ptr++;
- }
+ /* The 29k has a special kludge for the high 16 bit reloc.
+ Two relocations are emmited, R_IHIHALF, and
+ R_IHCONST. The second one doesn't contain a symbol,
+ but uses the value for offset */
+
+ if (intr.r_type == R_IHIHALF)
+ {
+ /* now emit the second bit */
+ intr.r_type = R_IHCONST;
+ intr.r_symndx = fix_ptr->fx_addnumber;
+ (void)bfd_coff_swap_reloc_out(abfd,&intr,ext_ptr);
+ ext_ptr++;
+ }
#endif
- }
-
- fix_ptr = fix_ptr->fx_next;
- }
-
- /* Write out the reloc table */
- segment_info[idx].scnhdr.s_relptr = *file_cursor;
- segment_info[idx].scnhdr.s_nreloc = nrelocs;
- bfd_write((PTR)external_reloc_vec, 1, external_reloc_size, abfd);
- *file_cursor += external_reloc_size;
- free( external_reloc_vec);
- }
- }
+ }
+
+ fix_ptr = fix_ptr->fx_next;
+ }
+
+ /* Write out the reloc table */
+ segment_info[idx].scnhdr.s_relptr = *file_cursor;
+ segment_info[idx].scnhdr.s_nreloc = nrelocs;
+ bfd_write((PTR)external_reloc_vec, 1, external_reloc_size, abfd);
+ *file_cursor += external_reloc_size;
+ free( external_reloc_vec);
+ }
+ }
}
/* run through a frag chain and write out the data to go with it, fill
in the scnhdrs with the info on the file postions
- */
+*/
static void DEFUN(fill_section,(abfd, filehdr, file_cursor),
bfd *abfd AND
struct internal_filehdr *filehdr AND
unsigned long *file_cursor)
{
-
- unsigned int i;
- unsigned int paddr = 0;
-
- for (i = SEG_E0; i < SEG_UNKNOWN; i++)
- {
- unsigned int offset = 0;
-
- struct internal_scnhdr *s = &( segment_info[i].scnhdr);
-
- if (s->s_name[0])
- {
- fragS *frag = segment_info[i].frchainP->frch_root;
- char *buffer = malloc(s->s_size);
- s->s_scnptr = *file_cursor;
- s->s_paddr = paddr;
- s->s_vaddr = paddr;
-
- s->s_flags = STYP_REG;
- if (strcmp(s->s_name,".text")==0)
- s->s_flags |= STYP_TEXT;
- else if (strcmp(s->s_name,".data")==0)
- s->s_flags |= STYP_DATA;
- else if (strcmp(s->s_name,".bss")==0)
- s->s_flags |= STYP_BSS | STYP_NOLOAD;
-
- while (frag) {
- unsigned int fill_size;
- switch (frag->fr_type) {
-
- case rs_fill:
- case rs_align:
- case rs_org:
- if(frag->fr_fix)
- {
- memcpy(buffer + frag->fr_address,
- frag->fr_literal,
- frag->fr_fix);
- offset += frag->fr_fix;
- }
-
- fill_size = frag->fr_var;
- if (fill_size)
- {
- unsigned int count ;
- unsigned int off = frag->fr_fix;
- for (count = frag->fr_offset; count; count--)
- {
- memcpy(buffer + frag->fr_address + off,
- frag->fr_literal + frag->fr_fix,
- fill_size);
- off += fill_size;
- offset += fill_size;
-
- }
-
- }
- break;
- default:
- abort();
- }
- frag = frag->fr_next;
- }
-
-
- bfd_write(buffer, s->s_size,1,abfd);
- free(buffer);
-
- *file_cursor += s->s_size;
- paddr += s->s_size;
- }
+
+ unsigned int i;
+ unsigned int paddr = 0;
+
+ for (i = SEG_E0; i < SEG_UNKNOWN; i++)
+ {
+ unsigned int offset = 0;
+
+ struct internal_scnhdr *s = &( segment_info[i].scnhdr);
+
+ if (s->s_name[0])
+ {
+ fragS *frag = segment_info[i].frchainP->frch_root;
+ char *buffer = malloc(s->s_size);
+ if (s->s_size != 0)
+ {
+ s->s_scnptr = *file_cursor;
+ s->s_paddr = paddr;
+ s->s_vaddr = paddr;
+
+ }
+ else
+ {
+ s->s_scnptr = 0;
+ s->s_paddr = 0;
+ s->s_vaddr = 0;
+
+ }
+
+
+ s->s_flags = STYP_REG;
+ if (strcmp(s->s_name,".text")==0)
+ s->s_flags |= STYP_TEXT;
+ else if (strcmp(s->s_name,".data")==0)
+ s->s_flags |= STYP_DATA;
+ else if (strcmp(s->s_name,".bss")==0)
+ s->s_flags |= STYP_BSS | STYP_NOLOAD;
+
+ while (frag) {
+ unsigned int fill_size;
+ switch (frag->fr_type) {
+
+ case rs_fill:
+ case rs_align:
+ case rs_org:
+ if(frag->fr_fix)
+ {
+ memcpy(buffer + frag->fr_address,
+ frag->fr_literal,
+ frag->fr_fix);
+ offset += frag->fr_fix;
+ }
+
+ fill_size = frag->fr_var;
+ if (fill_size)
+ {
+ unsigned int count ;
+ unsigned int off = frag->fr_fix;
+ for (count = frag->fr_offset; count; count--)
+ {
+ memcpy(buffer + frag->fr_address + off,
+ frag->fr_literal + frag->fr_fix,
+ fill_size);
+ off += fill_size;
+ offset += fill_size;
+
+ }
+
+ }
+ break;
+ default:
+ abort();
+ }
+ frag = frag->fr_next;
}
-
+
+
+ bfd_write(buffer, s->s_size,1,abfd);
+ free(buffer);
+
+ *file_cursor += s->s_size;
+ paddr += s->s_size;
+ }
+ }
+
}
@@ -510,74 +523,74 @@ static void DEFUN(fill_section,(abfd, filehdr, file_cursor),
static void
- DEFUN(coff_header_append,(abfd, filehdr, aouthdr),
- bfd *abfd AND
- struct internal_filehdr *filehdr AND
- struct internal_aouthdr *aouthdr)
+DEFUN(coff_header_append,(abfd, filehdr, aouthdr),
+ bfd *abfd AND
+ struct internal_filehdr *filehdr AND
+ struct internal_aouthdr *aouthdr)
{
- unsigned int i;
- char buffer[1000];
- char buffero[1000];
-
- bfd_seek(abfd, 0, 0);
+ unsigned int i;
+ char buffer[1000];
+ char buffero[1000];
+
+ bfd_seek(abfd, 0, 0);
#if 0
- filehdr.f_opthdr = bfd_coff_swap_aouthdr_out(abfd, aouthdr,
- buffero);
+ filehdr.f_opthdr = bfd_coff_swap_aouthdr_out(abfd, aouthdr,
+ buffero);
#else
- filehdr->f_opthdr = 0;
+ filehdr->f_opthdr = 0;
#endif
- i = bfd_coff_swap_filehdr_out(abfd, filehdr, buffer);
-
- bfd_write(buffer, i ,1, abfd);
- bfd_write(buffero, filehdr->f_opthdr, 1, abfd);
-
- for (i = SEG_E0; i < SEG_E9; i++)
- {
- if (segment_info[i].scnhdr.s_name[0])
- {
- unsigned int size =
- bfd_coff_swap_scnhdr_out(abfd,
- &(segment_info[i].scnhdr),
- buffer);
- bfd_write(buffer, size, 1, abfd);
- }
- }
+ i = bfd_coff_swap_filehdr_out(abfd, filehdr, buffer);
+
+ bfd_write(buffer, i ,1, abfd);
+ bfd_write(buffero, filehdr->f_opthdr, 1, abfd);
+
+ for (i = SEG_E0; i < SEG_E9; i++)
+ {
+ if (segment_info[i].scnhdr.s_name[0])
+ {
+ unsigned int size =
+ bfd_coff_swap_scnhdr_out(abfd,
+ &(segment_info[i].scnhdr),
+ buffer);
+ bfd_write(buffer, size, 1, abfd);
+ }
+ }
}
char *
- DEFUN(symbol_to_chars,(abfd, where, symbolP),
- bfd*abfd AND
- char *where AND
- symbolS *symbolP)
+DEFUN(symbol_to_chars,(abfd, where, symbolP),
+ bfd*abfd AND
+ char *where AND
+ symbolS *symbolP)
{
- unsigned int numaux = symbolP->sy_symbol.ost_entry.n_numaux;
- unsigned int i;
-
- /* Turn any symbols with register attributes into abs symbols */
- if (S_GET_SEGMENT(symbolP) == SEG_REGISTER)
- {
- S_SET_SEGMENT(symbolP, SEG_ABSOLUTE);
- }
- /* At the same time, relocate all symbols to their output value */
-
- S_SET_VALUE(symbolP,
- segment_info[S_GET_SEGMENT(symbolP)].scnhdr.s_paddr
- + S_GET_VALUE(symbolP));
-
- where += bfd_coff_swap_sym_out(abfd, &symbolP->sy_symbol.ost_entry,
+ unsigned int numaux = symbolP->sy_symbol.ost_entry.n_numaux;
+ unsigned int i;
+
+ /* Turn any symbols with register attributes into abs symbols */
+ if (S_GET_SEGMENT(symbolP) == SEG_REGISTER)
+ {
+ S_SET_SEGMENT(symbolP, SEG_ABSOLUTE);
+ }
+ /* At the same time, relocate all symbols to their output value */
+
+ S_SET_VALUE(symbolP,
+ segment_info[S_GET_SEGMENT(symbolP)].scnhdr.s_paddr
+ + S_GET_VALUE(symbolP));
+
+ where += bfd_coff_swap_sym_out(abfd, &symbolP->sy_symbol.ost_entry,
+ where);
+
+ for (i = 0; i < numaux; i++)
+ {
+ where += bfd_coff_swap_aux_out(abfd,
+ &symbolP->sy_symbol.ost_auxent[i],
+ S_GET_DATA_TYPE(symbolP),
+ S_GET_STORAGE_CLASS(symbolP),
where);
-
- for (i = 0; i < numaux; i++)
- {
- where += bfd_coff_swap_aux_out(abfd,
- &symbolP->sy_symbol.ost_auxent[i],
- S_GET_DATA_TYPE(symbolP),
- S_GET_STORAGE_CLASS(symbolP),
- where);
- }
- return where;
-
+ }
+ return where;
+
}
@@ -587,7 +600,7 @@ void obj_symbol_new_hook(symbolP)
symbolS *symbolP;
{
char underscore = 0; /* Symbol has leading _ */
-
+
/* Effective symbol */
/* Store the pointer in the offset. */
S_SET_ZEROES(symbolP, 0L);
@@ -597,8 +610,8 @@ symbolS *symbolP;
/* Additional information */
symbolP->sy_symbol.ost_flags = 0;
/* Auxiliary entries */
- memset((char*) &symbolP->sy_symbol.ost_auxent[0], '\0', AUXESZ);
-
+ bzero((char*)&symbolP->sy_symbol.ost_auxent[0], AUXESZ);
+
#ifdef STRIP_UNDERSCORE
/* Remove leading underscore at the beginning of the symbol.
* This is to be compatible with the standard librairies.
@@ -608,22 +621,22 @@ symbolS *symbolP;
S_SET_NAME(symbolP, S_GET_NAME(symbolP) + 1);
} /* strip underscore */
#endif /* STRIP_UNDERSCORE */
-
+
if (S_IS_STRING(symbolP))
SF_SET_STRING(symbolP);
if (!underscore && S_IS_LOCAL(symbolP))
SF_SET_LOCAL(symbolP);
-
+
return;
} /* obj_symbol_new_hook() */
-/* stack stuff */
+ /* stack stuff */
stack* stack_init(chunk_size, element_size)
unsigned long chunk_size;
unsigned long element_size;
{
stack* st;
-
+
if ((st = (stack*)malloc(sizeof(stack))) == (stack*)0)
return (stack*)0;
if ((st->data = malloc(chunk_size)) == (char*)0) {
@@ -640,8 +653,8 @@ unsigned long element_size;
void stack_delete(st)
stack* st;
{
- free(st->data);
- free(st);
+ free(st->data);
+ free(st);
}
char *stack_push(st, element)
@@ -661,18 +674,18 @@ char *element;
char* stack_pop(st)
stack* st;
{
- if ((st->pointer -= st->element_size) < 0) {
- st->pointer = 0;
- return (char*)0;
- }
-
- return st->data + st->pointer;
+ if ((st->pointer -= st->element_size) < 0) {
+ st->pointer = 0;
+ return (char*)0;
+ }
+
+ return st->data + st->pointer;
}
char* stack_top(st)
stack* st;
{
- return st->data + st->pointer - st->element_size;
+ return st->data + st->pointer - st->element_size;
}
@@ -682,31 +695,31 @@ stack* st;
static void obj_coff_ln()
{
- int l;
-
- if (def_symbol_in_progress != NULL) {
- as_warn(".ln pseudo-op inside .def/.endef: ignored.");
- demand_empty_rest_of_line();
- return;
- } /* wrong context */
-
- c_line_new(0,
- obstack_next_free(&frags) - frag_now->fr_literal,
- l = get_absolute_expression(),
- frag_now);
+ int l;
+
+ if (def_symbol_in_progress != NULL) {
+ as_warn(".ln pseudo-op inside .def/.endef: ignored.");
+ demand_empty_rest_of_line();
+ return;
+ } /* wrong context */
+
+ c_line_new(0,
+ obstack_next_free(&frags) - frag_now->fr_literal,
+ l = get_absolute_expression(),
+ frag_now);
#ifndef NO_LISTING
- {
- extern int listing;
-
- if (listing)
- {
- listing_source_line(l + line_base - 1);
- }
-
- }
+{
+ extern int listing;
+
+ if (listing)
+ {
+ listing_source_line(l + line_base - 1);
+ }
+
+}
#endif
- demand_empty_rest_of_line();
- return;
+ demand_empty_rest_of_line();
+ return;
} /* obj_coff_line() */
/*
@@ -725,163 +738,164 @@ static void obj_coff_ln()
#define SKIP_SEMI_COLON() while (*input_line_pointer++ != ';')
#define SKIP_WHITESPACES() while (*input_line_pointer == ' ' || \
- *input_line_pointer == '\t') \
- input_line_pointer++;
+ *input_line_pointer == '\t') \
+ input_line_pointer++;
static void
- DEFUN(obj_coff_def,(what),
- int what)
+DEFUN(obj_coff_def,(what),
+ int what)
{
- char name_end; /* Char after the end of name */
- char *symbol_name; /* Name of the debug symbol */
- char *symbol_name_copy; /* Temporary copy of the name */
- unsigned int symbol_name_length;
- /*$char* directiveP;$ */ /* Name of the pseudo opcode */
- /*$char directive[MAX_DIRECTIVE];$ */ /* Backup of the directive */
- /*$char end = 0;$ */ /* If 1, stop parsing */
-
- if (def_symbol_in_progress != NULL) {
- as_warn(".def pseudo-op used inside of .def/.endef: ignored.");
- demand_empty_rest_of_line();
- return;
+ char name_end; /* Char after the end of name */
+ char *symbol_name; /* Name of the debug symbol */
+ char *symbol_name_copy; /* Temporary copy of the name */
+ unsigned int symbol_name_length;
+ /*$char* directiveP;$ */ /* Name of the pseudo opcode */
+ /*$char directive[MAX_DIRECTIVE];$ */ /* Backup of the directive */
+ /*$char end = 0;$ */ /* If 1, stop parsing */
+
+ if (def_symbol_in_progress != NULL) {
+ as_warn(".def pseudo-op used inside of .def/.endef: ignored.");
+ demand_empty_rest_of_line();
+ return;
} /* if not inside .def/.endef */
-
- SKIP_WHITESPACES();
-
- def_symbol_in_progress = (symbolS *) obstack_alloc(&notes, sizeof(*def_symbol_in_progress));
- memset(def_symbol_in_progress, '\0', sizeof(*def_symbol_in_progress));
-
- symbol_name = input_line_pointer;
- name_end = get_symbol_end();
- symbol_name_length = strlen(symbol_name);
- symbol_name_copy = xmalloc(symbol_name_length + 1);
- strcpy(symbol_name_copy, symbol_name);
-
- /* Initialize the new symbol */
+
+ SKIP_WHITESPACES();
+
+ def_symbol_in_progress = (symbolS *) obstack_alloc(&notes, sizeof(*def_symbol_in_progress));
+ bzero(def_symbol_in_progress, sizeof(*def_symbol_in_progress));
+
+ symbol_name = input_line_pointer;
+ name_end = get_symbol_end();
+ symbol_name_length = strlen(symbol_name);
+ symbol_name_copy = xmalloc(symbol_name_length + 1);
+ strcpy(symbol_name_copy, symbol_name);
+
+ /* Initialize the new symbol */
#ifdef STRIP_UNDERSCORE
- S_SET_NAME(def_symbol_in_progress, (*symbol_name_copy == '_'
- ? symbol_name_copy + 1
- : symbol_name_copy));
+ S_SET_NAME(def_symbol_in_progress, (*symbol_name_copy == '_'
+ ? symbol_name_copy + 1
+ : symbol_name_copy));
#else /* STRIP_UNDERSCORE */
- S_SET_NAME(def_symbol_in_progress, symbol_name_copy);
+ S_SET_NAME(def_symbol_in_progress, symbol_name_copy);
#endif /* STRIP_UNDERSCORE */
- /* free(symbol_name_copy); */
- def_symbol_in_progress->sy_name_offset = ~0;
- def_symbol_in_progress->sy_number = ~0;
- def_symbol_in_progress->sy_frag = &zero_address_frag;
-
- if (S_IS_STRING(def_symbol_in_progress)) {
- SF_SET_STRING(def_symbol_in_progress);
+ /* free(symbol_name_copy); */
+ def_symbol_in_progress->sy_name_offset = ~0;
+ def_symbol_in_progress->sy_number = ~0;
+ def_symbol_in_progress->sy_frag = &zero_address_frag;
+
+ if (S_IS_STRING(def_symbol_in_progress)) {
+ SF_SET_STRING(def_symbol_in_progress);
} /* "long" name */
-
- *input_line_pointer = name_end;
-
- demand_empty_rest_of_line();
- return;
+
+ *input_line_pointer = name_end;
+
+ demand_empty_rest_of_line();
+ return;
} /* obj_coff_def() */
unsigned int dim_index;
static void
- DEFUN_VOID(obj_coff_endef)
+DEFUN_VOID(obj_coff_endef)
{
- symbolS *symbolP = 0;
- /* DIM BUG FIX sac@cygnus.com */
- dim_index =0;
- if (def_symbol_in_progress == NULL) {
- as_warn(".endef pseudo-op used outside of .def/.endef: ignored.");
- demand_empty_rest_of_line();
- return;
+ symbolS *symbolP = 0;
+ /* DIM BUG FIX sac@cygnus.com */
+ dim_index =0;
+ if (def_symbol_in_progress == NULL) {
+ as_warn(".endef pseudo-op used outside of .def/.endef: ignored.");
+ demand_empty_rest_of_line();
+ return;
} /* if not inside .def/.endef */
-
- /* Set the section number according to storage class. */
- switch (S_GET_STORAGE_CLASS(def_symbol_in_progress)) {
- case C_STRTAG:
- case C_ENTAG:
- case C_UNTAG:
- SF_SET_TAG(def_symbol_in_progress);
- /* intentional fallthrough */
- case C_FILE:
- case C_TPDEF:
- SF_SET_DEBUG(def_symbol_in_progress);
- S_SET_SEGMENT(def_symbol_in_progress, SEG_DEBUG);
- break;
-
- case C_EFCN:
- SF_SET_LOCAL(def_symbol_in_progress); /* Do not emit this symbol. */
- /* intentional fallthrough */
- case C_BLOCK:
- SF_SET_PROCESS(def_symbol_in_progress); /* Will need processing before writing */
- /* intentional fallthrough */
- case C_FCN:
- S_SET_SEGMENT(def_symbol_in_progress, SEG_E0);
-
- if (def_symbol_in_progress->sy_symbol.ost_entry.n_name[1] == 'b') { /* .bf */
- if (function_lineoff < 0) {
- fprintf(stderr, "`.bf' symbol without preceding function\n");
+
+ /* Set the section number according to storage class. */
+ switch (S_GET_STORAGE_CLASS(def_symbol_in_progress)) {
+ case C_STRTAG:
+ case C_ENTAG:
+ case C_UNTAG:
+ SF_SET_TAG(def_symbol_in_progress);
+ /* intentional fallthrough */
+ case C_FILE:
+ case C_TPDEF:
+ SF_SET_DEBUG(def_symbol_in_progress);
+ S_SET_SEGMENT(def_symbol_in_progress, SEG_DEBUG);
+ break;
+
+ case C_EFCN:
+ SF_SET_LOCAL(def_symbol_in_progress); /* Do not emit this symbol. */
+ /* intentional fallthrough */
+ case C_BLOCK:
+ SF_SET_PROCESS(def_symbol_in_progress); /* Will need processing before writing */
+ /* intentional fallthrough */
+ case C_FCN:
+ S_SET_SEGMENT(def_symbol_in_progress, SEG_E0);
+
+ if (def_symbol_in_progress->sy_symbol.ost_entry._n._n_nptr[1][1] == 'b') { /* .bf */
+ if (function_lineoff < 0) {
+ fprintf(stderr, "`.bf' symbol without preceding function\n");
} /* missing function symbol */
- SA_GET_SYM_LNNOPTR(def_symbol_in_progress) = function_lineoff;
- SF_SET_PROCESS(def_symbol_in_progress); /* Will need relocating */
- function_lineoff = -1;
+ SA_GET_SYM_LNNOPTR(last_line_symbol) = function_lineoff;
+
+ SF_SET_PROCESS(last_line_symbol);
+ function_lineoff = -1;
}
- break;
-
+ break;
+
#ifdef C_AUTOARG
- case C_AUTOARG:
+ case C_AUTOARG:
#endif /* C_AUTOARG */
- case C_AUTO:
- case C_REG:
- case C_MOS:
- case C_MOE:
- case C_MOU:
- case C_ARG:
- case C_REGPARM:
- case C_FIELD:
- case C_EOS:
- SF_SET_DEBUG(def_symbol_in_progress);
- S_SET_SEGMENT(def_symbol_in_progress, SEG_ABSOLUTE);
- break;
-
- case C_EXT:
- case C_STAT:
- case C_LABEL:
- /* Valid but set somewhere else (s_comm, s_lcomm, colon) */
- break;
-
- case C_USTATIC:
- case C_EXTDEF:
- case C_ULABEL:
- as_warn("unexpected storage class %d", S_GET_STORAGE_CLASS(def_symbol_in_progress));
- break;
+ case C_AUTO:
+ case C_REG:
+ case C_MOS:
+ case C_MOE:
+ case C_MOU:
+ case C_ARG:
+ case C_REGPARM:
+ case C_FIELD:
+ case C_EOS:
+ SF_SET_DEBUG(def_symbol_in_progress);
+ S_SET_SEGMENT(def_symbol_in_progress, SEG_ABSOLUTE);
+ break;
+
+ case C_EXT:
+ case C_STAT:
+ case C_LABEL:
+ /* Valid but set somewhere else (s_comm, s_lcomm, colon) */
+ break;
+
+ case C_USTATIC:
+ case C_EXTDEF:
+ case C_ULABEL:
+ as_warn("unexpected storage class %d", S_GET_STORAGE_CLASS(def_symbol_in_progress));
+ break;
} /* switch on storage class */
-
- /* Now that we have built a debug symbol, try to
- find if we should merge with an existing symbol
- or not. If a symbol is C_EFCN or SEG_ABSOLUTE or
- untagged SEG_DEBUG it never merges. */
-
- /* Two cases for functions. Either debug followed
- by definition or definition followed by debug.
- For definition first, we will merge the debug
- symbol into the definition. For debug first, the
- lineno entry MUST point to the definition
- function or else it will point off into space
- when crawl_symbols() merges the debug
- symbol into the real symbol. Therefor, let's
- presume the debug symbol is a real function
- reference. */
-
- /* FIXME-SOON If for some reason the definition
- label/symbol is never seen, this will probably
- leave an undefined symbol at link time. */
-
- if (S_GET_STORAGE_CLASS(def_symbol_in_progress) == C_EFCN
- || (S_GET_SEGMENT(def_symbol_in_progress) == SEG_DEBUG
- && !SF_GET_TAG(def_symbol_in_progress))
- || S_GET_SEGMENT(def_symbol_in_progress) == SEG_ABSOLUTE
- || (symbolP = symbol_find_base(S_GET_NAME(def_symbol_in_progress), DO_NOT_STRIP)) == NULL) {
-
- symbol_append(def_symbol_in_progress, symbol_lastP, &symbol_rootP, &symbol_lastP);
-
+
+ /* Now that we have built a debug symbol, try to
+ find if we should merge with an existing symbol
+ or not. If a symbol is C_EFCN or SEG_ABSOLUTE or
+ untagged SEG_DEBUG it never merges. */
+
+ /* Two cases for functions. Either debug followed
+ by definition or definition followed by debug.
+ For definition first, we will merge the debug
+ symbol into the definition. For debug first, the
+ lineno entry MUST point to the definition
+ function or else it will point off into space
+ when crawl_symbols() merges the debug
+ symbol into the real symbol. Therefor, let's
+ presume the debug symbol is a real function
+ reference. */
+
+ /* FIXME-SOON If for some reason the definition
+ label/symbol is never seen, this will probably
+ leave an undefined symbol at link time. */
+
+ if (S_GET_STORAGE_CLASS(def_symbol_in_progress) == C_EFCN
+ || (S_GET_SEGMENT(def_symbol_in_progress) == SEG_DEBUG
+ && !SF_GET_TAG(def_symbol_in_progress))
+ || S_GET_SEGMENT(def_symbol_in_progress) == SEG_ABSOLUTE
+ || (symbolP = symbol_find_base(S_GET_NAME(def_symbol_in_progress), DO_NOT_STRIP)) == NULL) {
+
+ symbol_append(def_symbol_in_progress, symbol_lastP, &symbol_rootP, &symbol_lastP);
+
} else {
/* This symbol already exists, merge the
newly created symbol into the old one.
@@ -890,14 +904,14 @@ static void
guess that it save a *lot* of space if
the assembly file defines a lot of
symbols. [loic] */
-
+
/* The debug entry (def_symbol_in_progress)
is merged into the previous definition. */
-
+
c_symbol_merge(def_symbol_in_progress, symbolP);
/* FIXME-SOON Should *def_symbol_in_progress be free'd? xoxorich. */
def_symbol_in_progress = symbolP;
-
+
if (SF_GET_FUNCTION(def_symbol_in_progress)
|| SF_GET_TAG(def_symbol_in_progress)) {
/* For functions, and tags, the symbol *must* be where the debug symbol
@@ -906,105 +920,105 @@ static void
if (def_symbol_in_progress != symbol_lastP) {
symbol_remove(def_symbol_in_progress, &symbol_rootP, &symbol_lastP);
symbol_append(def_symbol_in_progress, symbol_lastP, &symbol_rootP, &symbol_lastP);
- } /* if not already in place */
- } /* if function */
- } /* normal or mergable */
-
- if (SF_GET_TAG(def_symbol_in_progress)
- && symbol_find_base(S_GET_NAME(def_symbol_in_progress), DO_NOT_STRIP) == NULL) {
- tag_insert(S_GET_NAME(def_symbol_in_progress), def_symbol_in_progress);
+ } /* if not already in place */
+ } /* if function */
+ } /* normal or mergable */
+
+ if (SF_GET_TAG(def_symbol_in_progress)
+ && symbol_find_base(S_GET_NAME(def_symbol_in_progress), DO_NOT_STRIP) == NULL) {
+ tag_insert(S_GET_NAME(def_symbol_in_progress), def_symbol_in_progress);
} /* If symbol is a {structure,union} tag, associate symbol to its name. */
-
- if (SF_GET_FUNCTION(def_symbol_in_progress)) {
- know(sizeof(def_symbol_in_progress) <= sizeof(long));
- function_lineoff
- = c_line_new(def_symbol_in_progress,0, 0, &zero_address_frag);
-
-
-
- SF_SET_PROCESS(def_symbol_in_progress);
-
- if (symbolP == NULL) {
- /* That is, if this is the first
- time we've seen the function... */
- symbol_table_insert(def_symbol_in_progress);
+
+ if (SF_GET_FUNCTION(def_symbol_in_progress)) {
+ know(sizeof(def_symbol_in_progress) <= sizeof(long));
+ function_lineoff
+ = c_line_new(def_symbol_in_progress,0, 0, &zero_address_frag);
+
+
+
+ SF_SET_PROCESS(def_symbol_in_progress);
+
+ if (symbolP == NULL) {
+ /* That is, if this is the first
+ time we've seen the function... */
+ symbol_table_insert(def_symbol_in_progress);
} /* definition follows debug */
} /* Create the line number entry pointing to the function being defined */
-
- def_symbol_in_progress = NULL;
- demand_empty_rest_of_line();
- return;
+
+ def_symbol_in_progress = NULL;
+ demand_empty_rest_of_line();
+ return;
} /* obj_coff_endef() */
static void
- DEFUN_VOID(obj_coff_dim)
+DEFUN_VOID(obj_coff_dim)
{
- register int dim_index;
-
- if (def_symbol_in_progress == NULL)
- {
- as_warn(".dim pseudo-op used outside of .def/.endef: ignored.");
- demand_empty_rest_of_line();
- return;
- } /* if not inside .def/.endef */
-
- S_SET_NUMBER_AUXILIARY(def_symbol_in_progress, 1);
-
- for (dim_index = 0; dim_index < DIMNUM; dim_index++)
- {
- SKIP_WHITESPACES();
- SA_SET_SYM_DIMEN(def_symbol_in_progress, dim_index, get_absolute_expression());
-
- switch (*input_line_pointer)
- {
-
- case ',':
- input_line_pointer++;
- break;
-
- default:
- as_warn("badly formed .dim directive ignored");
- /* intentional fallthrough */
- case '\n':
- case ';':
- dim_index = DIMNUM;
- break;
- } /* switch on following character */
- } /* for each dimension */
-
+ register int dim_index;
+
+ if (def_symbol_in_progress == NULL)
+ {
+ as_warn(".dim pseudo-op used outside of .def/.endef: ignored.");
demand_empty_rest_of_line();
return;
+ } /* if not inside .def/.endef */
+
+ S_SET_NUMBER_AUXILIARY(def_symbol_in_progress, 1);
+
+ for (dim_index = 0; dim_index < DIMNUM; dim_index++)
+ {
+ SKIP_WHITESPACES();
+ SA_SET_SYM_DIMEN(def_symbol_in_progress, dim_index, get_absolute_expression());
+
+ switch (*input_line_pointer)
+ {
+
+ case ',':
+ input_line_pointer++;
+ break;
+
+ default:
+ as_warn("badly formed .dim directive ignored");
+ /* intentional fallthrough */
+ case '\n':
+ case ';':
+ dim_index = DIMNUM;
+ break;
+ } /* switch on following character */
+ } /* for each dimension */
+
+ demand_empty_rest_of_line();
+ return;
} /* obj_coff_dim() */
static void obj_coff_line()
{
- int this_base;
-
- if (def_symbol_in_progress == NULL) {
- obj_coff_ln();
- return;
- } /* if it looks like a stabs style line */
-
- this_base = get_absolute_expression();
- if (this_base > line_base)
- {
- line_base = this_base;
- }
-
-
+ int this_base;
+
+ if (def_symbol_in_progress == NULL) {
+ obj_coff_ln();
+ return;
+ } /* if it looks like a stabs style line */
+
+ this_base = get_absolute_expression();
+ if (this_base > line_base)
+ {
+ line_base = this_base;
+ }
+
+
#ifndef NO_LISTING
- {
- extern int listing;
- if (listing && 0) {
- listing_source_line(line_base);
- }
- }
+{
+ extern int listing;
+ if (listing && 0) {
+ listing_source_line(line_base);
+ }
+}
#endif
- S_SET_NUMBER_AUXILIARY(def_symbol_in_progress, 1);
- SA_SET_SYM_LNNO(def_symbol_in_progress, line_base);
-
- demand_empty_rest_of_line();
- return;
+ S_SET_NUMBER_AUXILIARY(def_symbol_in_progress, 1);
+ SA_SET_SYM_LNNO(def_symbol_in_progress, line_base);
+
+ demand_empty_rest_of_line();
+ return;
} /* obj_coff_line() */
static void obj_coff_size() {
@@ -1013,7 +1027,7 @@ static void obj_coff_size() {
demand_empty_rest_of_line();
return;
} /* if not inside .def/.endef */
-
+
S_SET_NUMBER_AUXILIARY(def_symbol_in_progress, 1);
SA_SET_SYM_SIZE(def_symbol_in_progress, get_absolute_expression());
demand_empty_rest_of_line();
@@ -1026,7 +1040,7 @@ static void obj_coff_scl() {
demand_empty_rest_of_line();
return;
} /* if not inside .def/.endef */
-
+
S_SET_STORAGE_CLASS(def_symbol_in_progress, get_absolute_expression());
demand_empty_rest_of_line();
return;
@@ -1035,27 +1049,27 @@ static void obj_coff_scl() {
static void obj_coff_tag() {
char *symbol_name;
char name_end;
-
+
if (def_symbol_in_progress == NULL) {
as_warn(".tag pseudo-op used outside of .def/.endef ignored.");
demand_empty_rest_of_line();
return;
} /* if not inside .def/.endef */
-
+
S_SET_NUMBER_AUXILIARY(def_symbol_in_progress, 1);
symbol_name = input_line_pointer;
name_end = get_symbol_end();
-
+
/* Assume that the symbol referred to by .tag is always defined. */
/* This was a bad assumption. I've added find_or_make. xoxorich. */
SA_SET_SYM_TAGNDX(def_symbol_in_progress, (long) tag_find_or_make(symbol_name));
if (SA_GET_SYM_TAGNDX(def_symbol_in_progress) == 0L) {
as_warn("tag not found for .tag %s", symbol_name);
} /* not defined */
-
+
SF_SET_TAGGED(def_symbol_in_progress);
*input_line_pointer = name_end;
-
+
demand_empty_rest_of_line();
return;
} /* obj_coff_tag() */
@@ -1066,14 +1080,14 @@ static void obj_coff_type() {
demand_empty_rest_of_line();
return;
} /* if not inside .def/.endef */
-
+
S_SET_DATA_TYPE(def_symbol_in_progress, get_absolute_expression());
-
+
if (ISFCN(S_GET_DATA_TYPE(def_symbol_in_progress)) &&
S_GET_STORAGE_CLASS(def_symbol_in_progress) != C_TPDEF) {
SF_SET_FUNCTION(def_symbol_in_progress);
} /* is a function */
-
+
demand_empty_rest_of_line();
return;
} /* obj_coff_type() */
@@ -1084,18 +1098,18 @@ static void obj_coff_val() {
demand_empty_rest_of_line();
return;
} /* if not inside .def/.endef */
-
+
if (is_name_beginner(*input_line_pointer)) {
char *symbol_name = input_line_pointer;
char name_end = get_symbol_end();
-
+
if (!strcmp(symbol_name, ".")) {
def_symbol_in_progress->sy_frag = frag_now;
S_SET_VALUE(def_symbol_in_progress, obstack_next_free(&frags) - frag_now->fr_literal);
/* If the .val is != from the .def (e.g. statics) */
} else if (strcmp(S_GET_NAME(def_symbol_in_progress), symbol_name)) {
def_symbol_in_progress->sy_forward = symbol_find_or_make(symbol_name);
-
+
/* If the segment is undefined when the forward
reference is solved, then copy the segment id
from the forward symbol. */
@@ -1106,7 +1120,7 @@ static void obj_coff_val() {
} else {
S_SET_VALUE(def_symbol_in_progress, get_absolute_expression());
} /* if symbol based */
-
+
demand_empty_rest_of_line();
return;
} /* obj_coff_val() */
@@ -1116,8 +1130,8 @@ static void obj_coff_val() {
*/
static void tag_init() {
- tag_hash = hash_new();
- return ;
+ tag_hash = hash_new();
+ return ;
} /* tag_init() */
static void tag_insert(name, symbolP)
@@ -1125,7 +1139,7 @@ char *name;
symbolS *symbolP;
{
register char * error_string;
-
+
if (*(error_string = hash_jam(tag_hash, name, (char *)symbolP))) {
as_fatal("Inserting \"%s\" into structure table failed: %s",
name, error_string);
@@ -1137,17 +1151,17 @@ static symbolS *tag_find_or_make(name)
char *name;
{
symbolS *symbolP;
-
+
if ((symbolP = tag_find(name)) == NULL) {
symbolP = symbol_new(name,
SEG_UNKNOWN,
0,
&zero_address_frag);
-
+
tag_insert(S_GET_NAME(symbolP), symbolP);
symbol_table_insert(symbolP);
} /* not found */
-
+
return(symbolP);
} /* tag_find_or_make() */
@@ -1161,13 +1175,13 @@ char *name;
} /* tag_find() */
void obj_read_begin_hook() {
- /* These had better be the same. Usually 18 bytes. */
+ /* These had better be the same. Usually 18 bytes. */
#ifndef BFD_HEADERS
know(sizeof(SYMENT) == sizeof(AUXENT));
know(SYMESZ == AUXESZ);
#endif
tag_init();
-
+
return;
} /* obj_read_begin_hook() */
@@ -1179,305 +1193,308 @@ symbolS *symbol_externP = NULL;
symbolS *symbol_extern_lastP = NULL;
stack*block_stack;
-symbolS *last_functionP = NULL;
-symbolS *last_tagP;
+ symbolS *last_functionP = NULL;
+ symbolS *last_tagP;
static unsigned int DEFUN_VOID(yank_symbols)
{
- symbolS *symbolP;
- unsigned int symbol_number =0;
-
- for (symbolP = symbol_rootP;
- symbolP;
- symbolP = symbolP ? symbol_next(symbolP) : symbol_rootP) {
- if (!SF_GET_DEBUG(symbolP)) {
- /* Debug symbols do not need all this rubbish */
- symbolS* real_symbolP;
-
- /* L* and C_EFCN symbols never merge. */
- if (!SF_GET_LOCAL(symbolP)
- && (real_symbolP = symbol_find_base(S_GET_NAME(symbolP), DO_NOT_STRIP))
- && real_symbolP != symbolP) {
- /* FIXME-SOON: where do dups come from?
- Maybe tag references before definitions? xoxorich. */
- /* Move the debug data from the debug symbol to the
- real symbol. Do NOT do the oposite (i.e. move from
- real symbol to debug symbol and remove real symbol from the
- list.) Because some pointers refer to the real symbol
- whereas no pointers refer to the debug symbol. */
- c_symbol_merge(symbolP, real_symbolP);
- /* Replace the current symbol by the real one */
- /* The symbols will never be the last or the first
- because : 1st symbol is .file and 3 last symbols are
- .text, .data, .bss */
- symbol_remove(real_symbolP, &symbol_rootP, &symbol_lastP);
- symbol_insert(real_symbolP, symbolP, &symbol_rootP, &symbol_lastP);
- symbol_remove(symbolP, &symbol_rootP, &symbol_lastP);
- symbolP = real_symbolP;
- } /* if not local but dup'd */
-
- if (flagseen['R'] && (S_GET_SEGMENT(symbolP) == SEG_E1)) {
- S_SET_SEGMENT(symbolP, SEG_E0);
- } /* push data into text */
-
- S_SET_VALUE(symbolP,
- S_GET_VALUE(symbolP) + symbolP->sy_frag->fr_address);
-
- if (!S_IS_DEFINED(symbolP) && !SF_GET_LOCAL(symbolP))
- {
- S_SET_EXTERNAL(symbolP);
- }
- else if (S_GET_STORAGE_CLASS(symbolP) == C_NULL)
- {
- if (S_GET_SEGMENT(symbolP) == SEG_E0)
- {
- S_SET_STORAGE_CLASS(symbolP, C_LABEL);
- }
- else
- {
- S_SET_STORAGE_CLASS(symbolP, C_STAT);
- }
- }
-
- /* Mainly to speed up if not -g */
- if (SF_GET_PROCESS(symbolP))
- {
- /* Handle the nested blocks auxiliary info. */
- if (S_GET_STORAGE_CLASS(symbolP) == C_BLOCK) {
- if (!strcmp(S_GET_NAME(symbolP), ".bb"))
- stack_push(block_stack, (char *) &symbolP);
- else { /* .eb */
- register symbolS* begin_symbolP;
- begin_symbolP = *(symbolS**)stack_pop(block_stack);
- if (begin_symbolP == (symbolS*)0)
- as_warn("mismatched .eb");
- else
- SA_SET_SYM_ENDNDX(begin_symbolP, symbol_number+2);
- }
- }
- /* If we are able to identify the type of a function, and we
- are out of a function (last_functionP == 0) then, the
- function symbol will be associated with an auxiliary
- entry. */
- if (last_functionP == (symbolS*)0 &&
- SF_GET_FUNCTION(symbolP)) {
- last_functionP = symbolP;
-
- if (S_GET_NUMBER_AUXILIARY(symbolP) < 1) {
- S_SET_NUMBER_AUXILIARY(symbolP, 1);
- } /* make it at least 1 */
-
- /* Clobber possible stale .dim information. */
- memset(symbolP->sy_symbol.ost_auxent[0].x_sym.x_fcnary.x_ary.x_dimen,
- '\0', sizeof(symbolP->sy_symbol.ost_auxent[0].x_sym.x_fcnary.x_ary.x_dimen));
- }
- /* The C_FCN doesn't need any additional information.
- I don't even know if this is needed for sdb. But the
- standard assembler generates it, so...
- */
- if (S_GET_STORAGE_CLASS(symbolP) == C_EFCN) {
- if (last_functionP == (symbolS*)0)
- as_fatal("C_EFCN symbol out of scope");
- SA_SET_SYM_FSIZE(last_functionP,
- (long)(S_GET_VALUE(symbolP) -
- S_GET_VALUE(last_functionP)));
- SA_SET_SYM_ENDNDX(last_functionP, symbol_number);
- last_functionP = (symbolS*)0;
- }
- }
- } else if (SF_GET_TAG(symbolP)) {
- /* First descriptor of a structure must point to
- the first slot after the structure description. */
- last_tagP = symbolP;
-
- } else if (S_GET_STORAGE_CLASS(symbolP) == C_EOS) {
- /* +2 take in account the current symbol */
- SA_SET_SYM_ENDNDX(last_tagP, symbol_number + 2);
- } else if (S_GET_STORAGE_CLASS(symbolP) == C_FILE) {
- if (S_GET_VALUE(symbolP)) {
- S_SET_VALUE((symbolS *) S_GET_VALUE(symbolP), symbol_number);
- S_SET_VALUE(symbolP, 0);
- } /* no one points at the first .file symbol */
- } /* if debug or tag or eos or file */
-
- /* We must put the external symbols apart. The loader
- does not bomb if we do not. But the references in
- the endndx field for a .bb symbol are not corrected
- if an external symbol is removed between .bb and .be.
- I.e in the following case :
- [20] .bb endndx = 22
- [21] foo external
- [22] .be
- ld will move the symbol 21 to the end of the list but
- endndx will still be 22 instead of 21. */
-
-
- if (SF_GET_LOCAL(symbolP)) {
- /* remove C_EFCN and LOCAL (L...) symbols */
- /* next pointer remains valid */
- symbol_remove(symbolP, &symbol_rootP, &symbol_lastP);
-
- }
- else if (!S_IS_DEFINED(symbolP)
- && !S_IS_DEBUG(symbolP)
- && !SF_GET_STATICS(symbolP) &&
- S_GET_STORAGE_CLASS(symbolP) == C_EXT)
- { /* C_EXT && !SF_GET_FUNCTION(symbolP)) */
- /* if external, Remove from the list */
- symbolS *hold = symbol_previous(symbolP);
-
- symbol_remove(symbolP, &symbol_rootP, &symbol_lastP);
- symbol_clear_list_pointers(symbolP);
- symbol_append(symbolP, symbol_extern_lastP, &symbol_externP, &symbol_extern_lastP);
- symbolP = hold;
- } else {
- if (SF_GET_STRING(symbolP)) {
- symbolP->sy_name_offset = string_byte_count;
- string_byte_count += strlen(S_GET_NAME(symbolP)) + 1;
- } else {
- symbolP->sy_name_offset = 0;
- } /* fix "long" names */
-
- symbolP->sy_number = symbol_number;
- symbol_number += 1 + S_GET_NUMBER_AUXILIARY(symbolP);
- } /* if local symbol */
- } /* traverse the symbol list */
- return symbol_number;
-
+ symbolS *symbolP;
+ unsigned int symbol_number =0;
+
+ for (symbolP = symbol_rootP;
+ symbolP;
+ symbolP = symbolP ? symbol_next(symbolP) : symbol_rootP) {
+ if (!SF_GET_DEBUG(symbolP)) {
+ /* Debug symbols do not need all this rubbish */
+ symbolS* real_symbolP;
+
+ /* L* and C_EFCN symbols never merge. */
+ if (!SF_GET_LOCAL(symbolP)
+ && (real_symbolP = symbol_find_base(S_GET_NAME(symbolP), DO_NOT_STRIP))
+ && real_symbolP != symbolP) {
+ /* FIXME-SOON: where do dups come from?
+ Maybe tag references before definitions? xoxorich. */
+ /* Move the debug data from the debug symbol to the
+ real symbol. Do NOT do the oposite (i.e. move from
+ real symbol to debug symbol and remove real symbol from the
+ list.) Because some pointers refer to the real symbol
+ whereas no pointers refer to the debug symbol. */
+ c_symbol_merge(symbolP, real_symbolP);
+ /* Replace the current symbol by the real one */
+ /* The symbols will never be the last or the first
+ because : 1st symbol is .file and 3 last symbols are
+ .text, .data, .bss */
+ symbol_remove(real_symbolP, &symbol_rootP, &symbol_lastP);
+ symbol_insert(real_symbolP, symbolP, &symbol_rootP, &symbol_lastP);
+ symbol_remove(symbolP, &symbol_rootP, &symbol_lastP);
+ symbolP = real_symbolP;
+ } /* if not local but dup'd */
+
+ if (flagseen['R'] && (S_GET_SEGMENT(symbolP) == SEG_E1)) {
+ S_SET_SEGMENT(symbolP, SEG_E0);
+ } /* push data into text */
+
+ S_SET_VALUE(symbolP,
+ S_GET_VALUE(symbolP) + symbolP->sy_frag->fr_address);
+
+ if (!S_IS_DEFINED(symbolP) && !SF_GET_LOCAL(symbolP))
+ {
+ S_SET_EXTERNAL(symbolP);
+ }
+ else if (S_GET_STORAGE_CLASS(symbolP) == C_NULL)
+ {
+ if (S_GET_SEGMENT(symbolP) == SEG_E0)
+ {
+ S_SET_STORAGE_CLASS(symbolP, C_LABEL);
+ }
+ else
+ {
+ S_SET_STORAGE_CLASS(symbolP, C_STAT);
+ }
+ }
+
+ /* Mainly to speed up if not -g */
+ if (SF_GET_PROCESS(symbolP))
+ {
+ /* Handle the nested blocks auxiliary info. */
+ if (S_GET_STORAGE_CLASS(symbolP) == C_BLOCK) {
+ if (!strcmp(S_GET_NAME(symbolP), ".bb"))
+ stack_push(block_stack, (char *) &symbolP);
+ else { /* .eb */
+ register symbolS* begin_symbolP;
+ begin_symbolP = *(symbolS**)stack_pop(block_stack);
+ if (begin_symbolP == (symbolS*)0)
+ as_warn("mismatched .eb");
+ else
+ SA_SET_SYM_ENDNDX(begin_symbolP, symbol_number+2);
+ }
+ }
+ /* If we are able to identify the type of a function, and we
+ are out of a function (last_functionP == 0) then, the
+ function symbol will be associated with an auxiliary
+ entry. */
+ if (last_functionP == (symbolS*)0 &&
+ SF_GET_FUNCTION(symbolP)) {
+ last_functionP = symbolP;
+
+ if (S_GET_NUMBER_AUXILIARY(symbolP) < 1) {
+ S_SET_NUMBER_AUXILIARY(symbolP, 1);
+ } /* make it at least 1 */
+
+ /* Clobber possible stale .dim information. */
+#if 0
+/* Iffed out by steve - this fries the lnnoptr info too */
+ bzero(symbolP->sy_symbol.ost_auxent[0].x_sym.x_fcnary.x_ary.x_dimen,
+ sizeof(symbolP->sy_symbol.ost_auxent[0].x_sym.x_fcnary.x_ary.x_dimen));
+#endif
+ }
+ /* The C_FCN doesn't need any additional information.
+ I don't even know if this is needed for sdb. But the
+ standard assembler generates it, so...
+ */
+ if (S_GET_STORAGE_CLASS(symbolP) == C_EFCN) {
+ if (last_functionP == (symbolS*)0)
+ as_fatal("C_EFCN symbol out of scope");
+ SA_SET_SYM_FSIZE(last_functionP,
+ (long)(S_GET_VALUE(symbolP) -
+ S_GET_VALUE(last_functionP)));
+ SA_SET_SYM_ENDNDX(last_functionP, symbol_number);
+ last_functionP = (symbolS*)0;
+ }
+ }
+ } else if (SF_GET_TAG(symbolP)) {
+ /* First descriptor of a structure must point to
+ the first slot after the structure description. */
+ last_tagP = symbolP;
+
+ } else if (S_GET_STORAGE_CLASS(symbolP) == C_EOS) {
+ /* +2 take in account the current symbol */
+ SA_SET_SYM_ENDNDX(last_tagP, symbol_number + 2);
+ } else if (S_GET_STORAGE_CLASS(symbolP) == C_FILE) {
+ if (S_GET_VALUE(symbolP)) {
+ S_SET_VALUE((symbolS *) S_GET_VALUE(symbolP), symbol_number);
+ S_SET_VALUE(symbolP, 0);
+ } /* no one points at the first .file symbol */
+ } /* if debug or tag or eos or file */
+
+ /* We must put the external symbols apart. The loader
+ does not bomb if we do not. But the references in
+ the endndx field for a .bb symbol are not corrected
+ if an external symbol is removed between .bb and .be.
+ I.e in the following case :
+ [20] .bb endndx = 22
+ [21] foo external
+ [22] .be
+ ld will move the symbol 21 to the end of the list but
+ endndx will still be 22 instead of 21. */
+
+
+ if (SF_GET_LOCAL(symbolP)) {
+ /* remove C_EFCN and LOCAL (L...) symbols */
+ /* next pointer remains valid */
+ symbol_remove(symbolP, &symbol_rootP, &symbol_lastP);
+
+ }
+ else if (!S_IS_DEFINED(symbolP)
+ && !S_IS_DEBUG(symbolP)
+ && !SF_GET_STATICS(symbolP) &&
+ S_GET_STORAGE_CLASS(symbolP) == C_EXT)
+ { /* C_EXT && !SF_GET_FUNCTION(symbolP)) */
+ /* if external, Remove from the list */
+ symbolS *hold = symbol_previous(symbolP);
+
+ symbol_remove(symbolP, &symbol_rootP, &symbol_lastP);
+ symbol_clear_list_pointers(symbolP);
+ symbol_append(symbolP, symbol_extern_lastP, &symbol_externP, &symbol_extern_lastP);
+ symbolP = hold;
+ } else {
+ if (SF_GET_STRING(symbolP)) {
+ symbolP->sy_name_offset = string_byte_count;
+ string_byte_count += strlen(S_GET_NAME(symbolP)) + 1;
+ } else {
+ symbolP->sy_name_offset = 0;
+ } /* fix "long" names */
+
+ symbolP->sy_number = symbol_number;
+ symbol_number += 1 + S_GET_NUMBER_AUXILIARY(symbolP);
+ } /* if local symbol */
+ } /* traverse the symbol list */
+ return symbol_number;
+
}
static unsigned int DEFUN_VOID(glue_symbols)
{
- unsigned int symbol_number = 0;
- symbolS *symbolP;
- for (symbolP = symbol_externP; symbol_externP;) {
- symbolS *tmp = symbol_externP;
-
- /* append */
- symbol_remove(tmp, &symbol_externP, &symbol_extern_lastP);
- symbol_append(tmp, symbol_lastP, &symbol_rootP, &symbol_lastP);
-
- /* and process */
- if (SF_GET_STRING(tmp)) {
- tmp->sy_name_offset = string_byte_count;
- string_byte_count += strlen(S_GET_NAME(tmp)) + 1;
- } else {
- tmp->sy_name_offset = 0;
- } /* fix "long" names */
-
- tmp->sy_number = symbol_number;
- symbol_number += 1 + S_GET_NUMBER_AUXILIARY(tmp);
- } /* append the entire extern chain */
- return symbol_number;
-
+ unsigned int symbol_number = 0;
+ symbolS *symbolP;
+ for (symbolP = symbol_externP; symbol_externP;) {
+ symbolS *tmp = symbol_externP;
+
+ /* append */
+ symbol_remove(tmp, &symbol_externP, &symbol_extern_lastP);
+ symbol_append(tmp, symbol_lastP, &symbol_rootP, &symbol_lastP);
+
+ /* and process */
+ if (SF_GET_STRING(tmp)) {
+ tmp->sy_name_offset = string_byte_count;
+ string_byte_count += strlen(S_GET_NAME(tmp)) + 1;
+ } else {
+ tmp->sy_name_offset = 0;
+ } /* fix "long" names */
+
+ tmp->sy_number = symbol_number;
+ symbol_number += 1 + S_GET_NUMBER_AUXILIARY(tmp);
+ } /* append the entire extern chain */
+ return symbol_number;
+
}
static unsigned int DEFUN_VOID(tie_tags)
{
- unsigned int symbol_number = 0;
-
- symbolS*symbolP;
- for (symbolP = symbol_rootP; symbolP; symbolP =
- symbol_next(symbolP))
- {
- symbolP->sy_number = symbol_number;
-
-
-
- if (SF_GET_TAGGED(symbolP))
- {
- SA_SET_SYM_TAGNDX
- (symbolP,
- ((symbolS*) SA_GET_SYM_TAGNDX(symbolP))->sy_number);
- }
-
- symbol_number += 1 + S_GET_NUMBER_AUXILIARY(symbolP);
- }
- return symbol_number;
-
+ unsigned int symbol_number = 0;
+
+ symbolS*symbolP;
+ for (symbolP = symbol_rootP; symbolP; symbolP =
+ symbol_next(symbolP))
+ {
+ symbolP->sy_number = symbol_number;
+
+
+
+ if (SF_GET_TAGGED(symbolP))
+ {
+ SA_SET_SYM_TAGNDX
+ (symbolP,
+ ((symbolS*) SA_GET_SYM_TAGNDX(symbolP))->sy_number);
+ }
+
+ symbol_number += 1 + S_GET_NUMBER_AUXILIARY(symbolP);
+ }
+ return symbol_number;
+
}
static void
- DEFUN(crawl_symbols,(headers, abfd),
- struct internal_filehdr *headers AND
- bfd *abfd)
+DEFUN(crawl_symbols,(headers, abfd),
+ struct internal_filehdr *headers AND
+ bfd *abfd)
{
-
- unsigned int i;
- unsigned int ptr = 0;
-
-
- symbolS *symbolP;
-
- /* Initialize the stack used to keep track of the matching .bb .be */
-
- block_stack = stack_init(512, sizeof(symbolS*));
- /* JF deal with forward references first... */
- for (symbolP = symbol_rootP;
- symbolP;
- symbolP = symbol_next(symbolP))
- {
-
- if (symbolP->sy_forward) {
- S_SET_VALUE(symbolP, (S_GET_VALUE(symbolP)
- + S_GET_VALUE(symbolP->sy_forward)
- + symbolP->sy_forward->sy_frag->fr_address));
-
- if (SF_GET_GET_SEGMENT(symbolP)) {
- S_SET_SEGMENT(symbolP, S_GET_SEGMENT(symbolP->sy_forward));
- } /* forward segment also */
-
- symbolP->sy_forward=0;
- } /* if it has a forward reference */
- } /* walk the symbol chain */
-
-
- /* The symbol list should be ordered according to the following sequence
- * order :
- * . .file symbol
- * . debug entries for functions
- * . fake symbols for the sections, including.text .data and .bss
- * . defined symbols
- * . undefined symbols
- * But this is not mandatory. The only important point is to put the
- * undefined symbols at the end of the list.
- */
-
- if (symbol_rootP == NULL
- || S_GET_STORAGE_CLASS(symbol_rootP) != C_FILE) {
- c_dot_file_symbol("fake");
- }
- /* Is there a .file symbol ? If not insert one at the beginning. */
-
- /*
- * Build up static symbols for the sections, they are filled in later
- */
-
-
- for (i = SEG_E0; i < SEG_E9; i++)
- {
- if (segment_info[i].scnhdr.s_name[0])
- {
- segment_info[i].dot =
- c_section_symbol(segment_info[i].scnhdr.s_name,
- i-SEG_E0+1);
-
- }
- }
-
-
- /* Take all the externals out and put them into another chain */
- headers->f_nsyms = yank_symbols();
- /* Take the externals and glue them onto the end.*/
- headers->f_nsyms += glue_symbols();
-
- headers->f_nsyms = tie_tags();
- know(symbol_externP == NULL);
- know(symbol_extern_lastP == NULL);
-
- return;
+
+ unsigned int i;
+ unsigned int ptr = 0;
+
+
+ symbolS *symbolP;
+
+ /* Initialize the stack used to keep track of the matching .bb .be */
+
+ block_stack = stack_init(512, sizeof(symbolS*));
+ /* JF deal with forward references first... */
+ for (symbolP = symbol_rootP;
+ symbolP;
+ symbolP = symbol_next(symbolP))
+ {
+
+ if (symbolP->sy_forward) {
+ S_SET_VALUE(symbolP, (S_GET_VALUE(symbolP)
+ + S_GET_VALUE(symbolP->sy_forward)
+ + symbolP->sy_forward->sy_frag->fr_address));
+
+ if (SF_GET_GET_SEGMENT(symbolP)) {
+ S_SET_SEGMENT(symbolP, S_GET_SEGMENT(symbolP->sy_forward));
+ } /* forward segment also */
+
+ symbolP->sy_forward=0;
+ } /* if it has a forward reference */
+ } /* walk the symbol chain */
+
+
+ /* The symbol list should be ordered according to the following sequence
+ * order :
+ * . .file symbol
+ * . debug entries for functions
+ * . fake symbols for the sections, including.text .data and .bss
+ * . defined symbols
+ * . undefined symbols
+ * But this is not mandatory. The only important point is to put the
+ * undefined symbols at the end of the list.
+ */
+
+ if (symbol_rootP == NULL
+ || S_GET_STORAGE_CLASS(symbol_rootP) != C_FILE) {
+ c_dot_file_symbol("fake");
+ }
+ /* Is there a .file symbol ? If not insert one at the beginning. */
+
+ /*
+ * Build up static symbols for the sections, they are filled in later
+ */
+
+
+ for (i = SEG_E0; i < SEG_E9; i++)
+ {
+ if (segment_info[i].scnhdr.s_name[0])
+ {
+ segment_info[i].dot =
+ c_section_symbol(segment_info[i].scnhdr.s_name,
+ i-SEG_E0+1);
+
+ }
+ }
+
+
+ /* Take all the externals out and put them into another chain */
+ headers->f_nsyms = yank_symbols();
+ /* Take the externals and glue them onto the end.*/
+ headers->f_nsyms += glue_symbols();
+
+ headers->f_nsyms = tie_tags();
+ know(symbol_externP == NULL);
+ know(symbol_extern_lastP == NULL);
+
+ return;
}
/*
@@ -1487,26 +1504,26 @@ static void
void DEFUN(w_strings,(where),
char *where)
{
- symbolS *symbolP;
-
- /* Gotta do md_ byte-ordering stuff for string_byte_count first - KWK */
- md_number_to_chars(where, string_byte_count, sizeof(string_byte_count));
- where += sizeof(string_byte_count);
- for (symbolP = symbol_rootP;
- symbolP;
- symbolP = symbol_next(symbolP))
- {
- unsigned int size;
-
- if (SF_GET_STRING(symbolP)) {
- size = strlen(S_GET_NAME(symbolP)) + 1;
-
- memcpy(where, S_GET_NAME(symbolP),size);
- where += size;
-
- }
- }
-
+ symbolS *symbolP;
+
+ /* Gotta do md_ byte-ordering stuff for string_byte_count first - KWK */
+ md_number_to_chars(where, string_byte_count, sizeof(string_byte_count));
+ where += sizeof(string_byte_count);
+ for (symbolP = symbol_rootP;
+ symbolP;
+ symbolP = symbol_next(symbolP))
+ {
+ unsigned int size;
+
+ if (SF_GET_STRING(symbolP)) {
+ size = strlen(S_GET_NAME(symbolP)) + 1;
+
+ memcpy(where, S_GET_NAME(symbolP),size);
+ where += size;
+
+ }
+ }
+
}
@@ -1514,59 +1531,59 @@ void DEFUN(w_strings,(where),
static void
- DEFUN(do_linenos_for,(abfd, file_cursor),
- bfd *abfd AND
- unsigned long *file_cursor)
+DEFUN(do_linenos_for,(abfd, file_cursor),
+ bfd *abfd AND
+ unsigned long *file_cursor)
{
- unsigned int idx;
+ unsigned int idx;
+
+ for (idx = SEG_E0; idx < SEG_E9; idx++)
+ {
+ segment_info_type *s = segment_info + idx;
+
+
+ if (s->scnhdr.s_nlnno != 0)
+ {
+ struct lineno_list *line_ptr ;
+
+ struct external_lineno *buffer =
+ (struct external_lineno *)xmalloc(s->scnhdr.s_nlnno * LINESZ);
+
+ struct external_lineno *dst= buffer;
+
+ /* Run through the table we've built and turn it into its external
+ form, take this chance to remove duplicates */
+
+ for (line_ptr = s->lineno_list_head;
+ line_ptr != (struct lineno_list *)NULL;
+ line_ptr = line_ptr->next)
+ {
+
+ if (line_ptr->line.l_lnno == 0)
+ {
+ /* Turn a pointer to a symbol into the symbols' index */
+ line_ptr->line.l_addr.l_symndx =
+ ( (symbolS *)line_ptr->line.l_addr.l_symndx)->sy_number;
+ }
+ else
+ {
+ line_ptr->line.l_addr.l_paddr += ((struct frag * )(line_ptr->frag))->fr_address;
+ }
+
+
+ (void) bfd_coff_swap_lineno_out(abfd, &(line_ptr->line), dst);
+ dst++;
- for (idx = SEG_E0; idx < SEG_E9; idx++)
- {
- segment_info_type *s = segment_info + idx;
-
-
- if (s->scnhdr.s_nlnno != 0)
- {
- struct lineno_list *line_ptr ;
-
- struct external_lineno *buffer =
- (struct external_lineno *)xmalloc(s->scnhdr.s_nlnno * LINESZ);
-
- struct external_lineno *dst= buffer;
-
- /* Run through the table we've built and turn it into its external
- form, take this chance to remove duplicates */
-
- for (line_ptr = s->lineno_list_head;
- line_ptr != (struct lineno_list *)NULL;
- line_ptr = line_ptr->next)
- {
-
- if (line_ptr->line.l_lnno == 0)
- {
- /* Turn a pointer to a symbol into the symbols' index */
- line_ptr->line.l_addr.l_symndx =
- ( (symbolS *)line_ptr->line.l_addr.l_symndx)->sy_number;
- }
- else
- {
- line_ptr->line.l_addr.l_paddr += ((struct frag * )(line_ptr->frag))->fr_address;
- }
-
-
- (void) bfd_coff_swap_lineno_out(abfd, &(line_ptr->line), dst);
- dst++;
-
- }
-
- s->scnhdr.s_lnnoptr = *file_cursor;
-
- bfd_write(buffer, 1, s->scnhdr.s_nlnno* LINESZ, abfd);
- free(buffer);
-
- *file_cursor += s->scnhdr.s_nlnno * LINESZ;
- }
- }
+ }
+
+ s->scnhdr.s_lnnoptr = *file_cursor;
+
+ bfd_write(buffer, 1, s->scnhdr.s_nlnno* LINESZ, abfd);
+ free(buffer);
+
+ *file_cursor += s->scnhdr.s_nlnno * LINESZ;
+ }
+ }
}
@@ -1576,216 +1593,230 @@ static void
static void DEFUN_VOID(remove_subsegs)
{
- unsigned int i;
+ unsigned int i;
+
+ for (i = SEG_E0; i < SEG_UNKNOWN; i++)
+ {
+ frchainS *head = segment_info[i].frchainP;
+ fragS dummy;
+ fragS * prev_frag = &dummy;
- for (i = SEG_E0; i < SEG_UNKNOWN; i++)
- {
- frchainS *head = segment_info[i].frchainP;
- fragS dummy;
- fragS * prev_frag = &dummy;
-
- while (head && head->frch_seg == i)
- {
- prev_frag->fr_next = head->frch_root;
- prev_frag = head->frch_last;
- head = head->frch_next;
- }
- prev_frag->fr_next = 0;
- }
+ while (head && head->frch_seg == i)
+ {
+ prev_frag->fr_next = head->frch_root;
+ prev_frag = head->frch_last;
+ head = head->frch_next;
+ }
+ prev_frag->fr_next = 0;
+ }
}
extern void DEFUN_VOID(write_object_file)
{
- int i;
- struct frchain *frchain_ptr;
-
- struct internal_filehdr filehdr;
- struct internal_aouthdr aouthdr;
- unsigned long file_cursor;
- bfd *abfd;
- unsigned int addr = 0;
- abfd = bfd_openw(out_file_name, TARGET_FORMAT);
-
-
- if (abfd == 0) {
- as_perror ("FATAL: Can't create %s", out_file_name);
- exit(42);
+ int i;
+ struct frchain *frchain_ptr;
+
+ struct internal_filehdr filehdr;
+ struct internal_aouthdr aouthdr;
+ unsigned long file_cursor;
+ bfd *abfd;
+ unsigned int addr = 0;
+ abfd = bfd_openw(out_file_name, TARGET_FORMAT);
+
+
+ if (abfd == 0) {
+ as_perror ("FATAL: Can't create %s", out_file_name);
+ exit(42);
}
- bfd_set_format(abfd, bfd_object);
- bfd_set_arch_mach(abfd, BFD_ARCH, 0);
-
-
-
- string_byte_count = 4;
-
- for (frchain_ptr = frchain_root;
- frchain_ptr != (struct frchain *)NULL;
- frchain_ptr = frchain_ptr->frch_next) {
- /* Run through all the sub-segments and align them up. Also close any
- open frags. We tack a .fill onto the end of the frag chain so
- that any .align's size can be worked by looking at the next
- frag */
-
- subseg_new(frchain_ptr->frch_seg, frchain_ptr->frch_subseg);
+ bfd_set_format(abfd, bfd_object);
+ bfd_set_arch_mach(abfd, BFD_ARCH, 0);
+
+
+
+ string_byte_count = 4;
+
+ for (frchain_ptr = frchain_root;
+ frchain_ptr != (struct frchain *)NULL;
+ frchain_ptr = frchain_ptr->frch_next) {
+ /* Run through all the sub-segments and align them up. Also close any
+ open frags. We tack a .fill onto the end of the frag chain so
+ that any .align's size can be worked by looking at the next
+ frag */
+
+ subseg_new(frchain_ptr->frch_seg, frchain_ptr->frch_subseg);
#define SUB_SEGMENT_ALIGN 1
- frag_align(SUB_SEGMENT_ALIGN,0);
- frag_wane(frag_now);
- frag_now->fr_fix = 0;
- know( frag_now->fr_next == NULL );
+ frag_align(SUB_SEGMENT_ALIGN,0);
+ frag_wane(frag_now);
+ frag_now->fr_fix = 0;
+ know( frag_now->fr_next == NULL );
}
-
-
- remove_subsegs();
-
-
- for (i = SEG_E0; i < SEG_UNKNOWN; i++)
- {
- relax_segment(segment_info[i].frchainP->frch_root, i);
- }
-
-
-
-
-
- filehdr.f_nscns = 0;
-
- /* Find out how big the sections are */
- for (i = SEG_E0; i < SEG_UNKNOWN; i++)
- {
-
- if (segment_info[i].scnhdr.s_name[0])
- {
- filehdr.f_nscns++;
- }
- segment_info[i].scnhdr.s_paddr = addr;
- if (i == SEG_E2) {
- /* THis is a special case, we leave the size alone, which will have */
- /* been made up from all and any lcomms seen */
- }
- else {
- addr += size_section(abfd, i);
- }
- }
-
-
-
- /* Turn the gas native symbol table shape into a coff symbol table */
- crawl_symbols(&filehdr, abfd);
-#ifndef TC_H8300
- for (i = SEG_E0; i < SEG_UNKNOWN; i++)
- {
- fixup_segment(segment_info[i].fix_root, i);
- }
-#endif
-
- file_cursor = FILHSZ + SCNHSZ * filehdr.f_nscns ;
-
- bfd_seek(abfd, file_cursor, 0);
-
-
- do_relocs_for(abfd, &file_cursor);
-
- do_linenos_for(abfd, &file_cursor);
-
-
- /* Plant the data */
-
- fill_section(abfd,&filehdr, &file_cursor);
-
- filehdr.f_magic = COFF_MAGIC;
- filehdr.f_timdat = 0;
- filehdr.f_flags = 0;
-
-
-
+
+
+ remove_subsegs();
+
+
+ for (i = SEG_E0; i < SEG_UNKNOWN; i++)
+ {
+ relax_segment(segment_info[i].frchainP->frch_root, i);
+ }
+
+
+
+
+
+ filehdr.f_nscns = 0;
+
+ /* Find out how big the sections are */
+ for (i = SEG_E0; i < SEG_UNKNOWN; i++)
+ {
+
+ if (segment_info[i].scnhdr.s_name[0])
{
-
- unsigned int symtable_size = filehdr.f_nsyms * SYMESZ;
- char *buffer1 = malloc(symtable_size + string_byte_count + 4);
- char *ptr = buffer1;
- filehdr.f_symptr = bfd_tell(abfd);
- w_symbols(abfd, buffer1, symbol_rootP);
- w_strings(buffer1 + symtable_size);
- bfd_write(buffer1, 1,symtable_size + string_byte_count + 4, abfd);
- free(buffer1);
-
+ filehdr.f_nscns++;
}
- coff_header_append(abfd, &filehdr, &aouthdr);
-
- bfd_close_all_done(abfd);
+
+ if (i == SEG_E2)
+ {
+ /* THis is a special case, we leave the size alone, which will have */
+ /* been made up from all and any lcomms seen */
+ }
+ else {
+ addr += size_section(abfd, i);
+ }
+ }
+
+
+
+ /* Turn the gas native symbol table shape into a coff symbol table */
+ crawl_symbols(&filehdr, abfd);
+#ifndef TC_H8300
+ for (i = SEG_E0; i < SEG_UNKNOWN; i++)
+ {
+ fixup_segment(segment_info[i].fix_root, i);
+ }
+#endif
+
+ file_cursor = FILHSZ + SCNHSZ * filehdr.f_nscns ;
+
+ bfd_seek(abfd, file_cursor, 0);
+
+
+ do_relocs_for(abfd, &file_cursor);
+
+ do_linenos_for(abfd, &file_cursor);
+
+
+ /* Plant the data */
+
+ fill_section(abfd,&filehdr, &file_cursor);
+
+ filehdr.f_magic = COFF_MAGIC;
+ filehdr.f_timdat = time(0);
+ filehdr.f_flags = COFF_FLAGS ;
+
+ if (!had_lineno)
+ {
+ filehdr.f_flags |= F_LNNO;
+ }
+ if (!had_reloc)
+ {
+ filehdr.f_flags |= F_RELFLG;
+ }
+
+
+
+
+
+
+
+ {
+
+ unsigned int symtable_size = filehdr.f_nsyms * SYMESZ;
+ char *buffer1 = malloc(symtable_size + string_byte_count + 4);
+ char *ptr = buffer1;
+ filehdr.f_symptr = bfd_tell(abfd);
+ w_symbols(abfd, buffer1, symbol_rootP);
+ w_strings(buffer1 + symtable_size);
+ bfd_write(buffer1, 1,symtable_size + string_byte_count + 4, abfd);
+ free(buffer1);
+
+ }
+ coff_header_append(abfd, &filehdr, &aouthdr);
+
+ bfd_close_all_done(abfd);
}
static void DEFUN(change_to_section,(name, len, exp),
- char *name AND
- unsigned int len AND
- unsigned int exp)
+ char *name AND
+ unsigned int len AND
+ unsigned int exp)
{
- unsigned int i;
- /* 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);
- subseg_new(i, exp);
+ unsigned int i;
+ /* 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);
+ subseg_new(i, exp);
}
static void
- DEFUN_VOID(obj_coff_section)
+DEFUN_VOID(obj_coff_section)
{
- /* Strip out the section name */
- char *section_name ;
- char *section_name_end;
- char c;
-
- unsigned int len;
- unsigned int exp;
-
- section_name = input_line_pointer;
- c = get_symbol_end();
- section_name_end = input_line_pointer;
-
- len = section_name_end - section_name ;
+ /* Strip out the section name */
+ char *section_name ;
+ char *section_name_end;
+ char c;
+
+ unsigned int len;
+ unsigned int exp;
+
+ section_name = input_line_pointer;
+ c = get_symbol_end();
+ section_name_end = input_line_pointer;
+
+ len = section_name_end - section_name ;
+ input_line_pointer++;
+ SKIP_WHITESPACE();
+ if (c == ',')
+ {
+ exp = get_absolute_expression();
+ }
+ else if ( *input_line_pointer == ',')
+ {
+
input_line_pointer++;
- SKIP_WHITESPACE();
- if (c == ',')
- {
- exp = get_absolute_expression();
- }
- else if ( *input_line_pointer == ',')
- {
-
- input_line_pointer++;
- exp = get_absolute_expression();
- }
- else
- {
- exp = 0;
- }
-
- change_to_section(section_name, len,exp);
- *section_name_end = c;
-
+ exp = get_absolute_expression();
+ }
+ else
+ {
+ exp = 0;
+ }
+
+ change_to_section(section_name, len,exp);
+*section_name_end = c;
+
}
static void obj_coff_text()
{
- change_to_section(".text",5, get_absolute_expression());
+ change_to_section(".text",5, get_absolute_expression());
}
static void obj_coff_data()
{
- change_to_section(".data",5, get_absolute_expression());
+ change_to_section(".data",5, get_absolute_expression());
}
void c_symbol_merge(debug, normal)
@@ -1794,97 +1825,100 @@ symbolS *normal;
{
S_SET_DATA_TYPE(normal, S_GET_DATA_TYPE(debug));
S_SET_STORAGE_CLASS(normal, S_GET_STORAGE_CLASS(debug));
-
+
if (S_GET_NUMBER_AUXILIARY(debug) > S_GET_NUMBER_AUXILIARY(normal)) {
S_SET_NUMBER_AUXILIARY(normal, S_GET_NUMBER_AUXILIARY(debug));
} /* take the most we have */
-
+
if (S_GET_NUMBER_AUXILIARY(debug) > 0) {
memcpy((char*)&normal->sy_symbol.ost_auxent[0], (char*)&debug->sy_symbol.ost_auxent[0], S_GET_NUMBER_AUXILIARY(debug) * AUXESZ);
} /* Move all the auxiliary information */
-
+
/* Move the debug flags. */
SF_SET_DEBUG_FIELD(normal, SF_GET_DEBUG_FIELD(debug));
} /* c_symbol_merge() */
static int
- DEFUN(c_line_new,(symbol, paddr, line_number, frag),
- symbolS *symbol AND
- long paddr AND
- unsigned short line_number AND
- fragS* frag)
+DEFUN(c_line_new,(symbol, paddr, line_number, frag),
+ symbolS *symbol AND
+ long paddr AND
+ unsigned short line_number AND
+ fragS* frag)
{
- struct lineno_list* new_line =
- (struct lineno_list *)xmalloc(sizeof(struct lineno_list));
-
- segment_info_type *s = segment_info + now_seg;
- new_line->line.l_lnno = line_number;
-
- if (line_number == 0)
- {
- new_line->line.l_addr.l_symndx = (long)symbol;
- }
- else
- {
- new_line->line.l_addr.l_paddr = paddr;
- }
-
- new_line->frag = (char*)frag;
- new_line->next = (struct lineno_list*)NULL;
-
-
- if (s->lineno_list_head == (struct lineno_list *)NULL)
- {
- s->lineno_list_head = new_line;
- }
- else
- {
- s->lineno_list_tail->next = new_line;
- }
- s->lineno_list_tail = new_line;
- return LINESZ * s->scnhdr.s_nlnno ++;
+ struct lineno_list* new_line =
+ (struct lineno_list *)xmalloc(sizeof(struct lineno_list));
+
+ segment_info_type *s = segment_info + now_seg;
+ new_line->line.l_lnno = line_number;
+
+ had_lineno = 1;
+
+ if (line_number == 0)
+ {
+last_line_symbol = symbol;
+ new_line->line.l_addr.l_symndx = (long)symbol;
+ }
+ else
+ {
+ new_line->line.l_addr.l_paddr = paddr;
+ }
+
+ new_line->frag = (char*)frag;
+ new_line->next = (struct lineno_list*)NULL;
+
+
+ if (s->lineno_list_head == (struct lineno_list *)NULL)
+ {
+ s->lineno_list_head = new_line;
+ }
+ else
+ {
+ s->lineno_list_tail->next = new_line;
+ }
+ s->lineno_list_tail = new_line;
+ return LINESZ * s->scnhdr.s_nlnno ++;
}
void c_dot_file_symbol(filename)
char *filename;
{
- symbolS* symbolP;
-
- symbolP = symbol_new(".file",
- SEG_DEBUG,
- 0,
- &zero_address_frag);
-
- S_SET_STORAGE_CLASS(symbolP, C_FILE);
- S_SET_NUMBER_AUXILIARY(symbolP, 1);
- SA_SET_FILE_FNAME(symbolP, filename);
+ symbolS* symbolP;
+
+ symbolP = symbol_new(".file",
+ SEG_DEBUG,
+ 0,
+ &zero_address_frag);
+
+ S_SET_STORAGE_CLASS(symbolP, C_FILE);
+ S_SET_NUMBER_AUXILIARY(symbolP, 1);
+ SA_SET_FILE_FNAME(symbolP, filename);
#ifndef NO_LISTING
- {
- extern int listing;
- if (listing)
- {
- listing_source_file(filename);
- }
-
- }
-
+ {
+ extern int listing;
+ if (listing)
+ {
+ listing_source_file(filename);
+ }
+
+ }
+
#endif
- SF_SET_DEBUG(symbolP);
- S_SET_VALUE(symbolP, (long) previous_file_symbol);
-
- previous_file_symbol = symbolP;
-
- /* Make sure that the symbol is first on the symbol chain */
- if (symbol_rootP != symbolP) {
- if (symbolP == symbol_lastP) {
- symbol_lastP = symbol_lastP->sy_previous;
- } /* if it was the last thing on the list */
-
- symbol_remove(symbolP, &symbol_rootP, &symbol_lastP);
- symbol_insert(symbolP, symbol_rootP, &symbol_rootP, &symbol_lastP);
- symbol_rootP = symbolP;
- } /* if not first on the list */
-
+ SF_SET_DEBUG(symbolP);
+ S_SET_VALUE(symbolP, (long) previous_file_symbol);
+
+ previous_file_symbol = symbolP;
+
+ /* Make sure that the symbol is first on the symbol chain */
+ if (symbol_rootP != symbolP) {
+ if (symbolP == symbol_lastP) {
+ symbol_lastP = symbol_lastP->sy_previous;
+ } /* if it was the last thing on the list */
+
+ symbol_remove(symbolP, &symbol_rootP, &symbol_lastP);
+ symbol_insert(symbolP, symbol_rootP, &symbol_rootP, &symbol_lastP);
+ symbol_rootP = symbolP;
+ } /* if not first on the list */
+
} /* c_dot_file_symbol() */
/*
@@ -1895,288 +1929,284 @@ symbolS *c_section_symbol(name,idx)
char *name;
int idx;
{
- symbolS *symbolP;
-
- symbolP = symbol_new(name,idx,
- 0,
- &zero_address_frag);
-
- S_SET_STORAGE_CLASS(symbolP, C_STAT);
- S_SET_NUMBER_AUXILIARY(symbolP, 1);
-
- SF_SET_STATICS(symbolP);
-
- return symbolP;
+ symbolS *symbolP;
+
+ symbolP = symbol_new(name,idx,
+ 0,
+ &zero_address_frag);
+
+ S_SET_STORAGE_CLASS(symbolP, C_STAT);
+ S_SET_NUMBER_AUXILIARY(symbolP, 1);
+
+ SF_SET_STATICS(symbolP);
+
+ return symbolP;
} /* c_section_symbol() */
static void
- DEFUN(w_symbols,(abfd, where, symbol_rootP),
- bfd *abfd AND
- char *where AND
- symbolS *symbol_rootP)
+DEFUN(w_symbols,(abfd, where, symbol_rootP),
+bfd *abfd AND
+char *where AND
+symbolS *symbol_rootP)
{
- symbolS *symbolP;
- unsigned int i;
-
- /* First fill in those values we have only just worked out */
- for (i = SEG_E0; i < SEG_E9; i++)
- {
- symbolP = segment_info[i].dot;
- if (symbolP)
- {
-
- SA_SET_SCN_SCNLEN(symbolP, segment_info[i].scnhdr.s_size);
- SA_SET_SCN_NRELOC(symbolP, segment_info[i].scnhdr.s_nreloc);
- SA_SET_SCN_NLINNO(symbolP, segment_info[i].scnhdr.s_nlnno);
-
- }
- }
-
- /*
- * Emit all symbols left in the symbol chain.
- */
- for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next(symbolP)) {
- /* Used to save the offset of the name. It is used to point
- to the string in memory but must be a file offset. */
- register char * temp;
-
- tc_coff_symbol_emit_hook(symbolP);
-
- temp = S_GET_NAME(symbolP);
- if (SF_GET_STRING(symbolP)) {
- S_SET_OFFSET(symbolP, symbolP->sy_name_offset);
- S_SET_ZEROES(symbolP, 0);
+ symbolS *symbolP;
+ unsigned int i;
+
+ /* First fill in those values we have only just worked out */
+ for (i = SEG_E0; i < SEG_E9; i++)
+ {
+ symbolP = segment_info[i].dot;
+ if (symbolP)
+ {
+
+ SA_SET_SCN_SCNLEN(symbolP, segment_info[i].scnhdr.s_size);
+ SA_SET_SCN_NRELOC(symbolP, segment_info[i].scnhdr.s_nreloc);
+ SA_SET_SCN_NLINNO(symbolP, segment_info[i].scnhdr.s_nlnno);
+
+ }
+ }
+
+ /*
+ * Emit all symbols left in the symbol chain.
+ */
+ for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next(symbolP)) {
+ /* Used to save the offset of the name. It is used to point
+ to the string in memory but must be a file offset. */
+ register char * temp;
+
+ tc_coff_symbol_emit_hook(symbolP);
+
+ temp = S_GET_NAME(symbolP);
+ if (SF_GET_STRING(symbolP)) {
+ S_SET_OFFSET(symbolP, symbolP->sy_name_offset);
+ S_SET_ZEROES(symbolP, 0);
} else {
- memset(symbolP->sy_symbol.ost_entry.n_name, '\0', SYMNMLEN);
+ bzero(symbolP->sy_symbol.ost_entry.n_name, SYMNMLEN);
strncpy(symbolP->sy_symbol.ost_entry.n_name, temp, SYMNMLEN);
- }
- where = symbol_to_chars(abfd, where, symbolP);
- S_SET_NAME(symbolP,temp);
+ }
+ where = symbol_to_chars(abfd, where, symbolP);
+ S_SET_NAME(symbolP,temp);
}
-
+
} /* w_symbols() */
static void DEFUN_VOID(obj_coff_lcomm)
{
- char *name;
- char c;
- int temp;
- char *p;
- symbolS *symbolP;
- name = input_line_pointer;
-
-
-
- c = get_symbol_end();
- p = input_line_pointer;
- *p = c;
- SKIP_WHITESPACE();
- if (*input_line_pointer != ',') {
- as_bad("Expected comma after name");
- ignore_rest_of_line();
- return;
+ char *name;
+ char c;
+ int temp;
+ char *p;
+ symbolS *symbolP;
+ name = input_line_pointer;
+
+
+
+ c = get_symbol_end();
+ p = input_line_pointer;
+ *p = c;
+ SKIP_WHITESPACE();
+ if (*input_line_pointer != ',') {
+ as_bad("Expected comma after name");
+ ignore_rest_of_line();
+ return;
}
- if (*input_line_pointer == '\n') {
- as_bad("Missing size expression");
- return;
+ if (*input_line_pointer == '\n') {
+ as_bad("Missing size expression");
+ return;
}
- input_line_pointer++;
- if ((temp = get_absolute_expression ()) < 0) {
- as_warn("lcomm length (%d.) <0! Ignored.", temp);
- ignore_rest_of_line();
- return;
+ input_line_pointer++;
+ if ((temp = get_absolute_expression ()) < 0) {
+ as_warn("lcomm length (%d.) <0! Ignored.", temp);
+ ignore_rest_of_line();
+ return;
}
- *p = 0;
- symbolP = symbol_find_or_make(name);
- S_SET_VALUE(symbolP, segment_info[SEG_E2].scnhdr.s_size);
- S_SET_SEGMENT(symbolP, SEG_E2);
- segment_info[SEG_E2].scnhdr.s_size += temp;
- S_SET_STORAGE_CLASS(symbolP, C_STAT);
- demand_empty_rest_of_line();
+ *p = 0;
+ symbolP = symbol_find_or_make(name);
+ S_SET_VALUE(symbolP, segment_info[SEG_E2].scnhdr.s_size);
+ S_SET_SEGMENT(symbolP, SEG_E2);
+ segment_info[SEG_E2].scnhdr.s_size += temp;
+ S_SET_STORAGE_CLASS(symbolP, C_STAT);
+ demand_empty_rest_of_line();
}
#if 1
static void DEFUN(fixup_segment,(fixP, this_segment_type),
- register fixS * fixP AND
- segT this_segment_type)
+register fixS * fixP AND
+segT this_segment_type)
{
- register symbolS *add_symbolP;
- register symbolS *sub_symbolP;
- register long add_number;
- register int size;
- register char *place;
- register long where;
- register char pcrel;
- register fragS *fragP;
- register segT add_symbol_segment = SEG_ABSOLUTE;
-
-
- for ( ; fixP; fixP = fixP->fx_next)
- {
- fragP = fixP->fx_frag;
- know(fragP);
- where = fixP->fx_where;
- place = fragP->fr_literal + where;
- size = fixP->fx_size;
- add_symbolP = fixP->fx_addsy;
+ register symbolS *add_symbolP;
+ register symbolS *sub_symbolP;
+ register long add_number;
+ register int size;
+ register char *place;
+ register long where;
+ register char pcrel;
+ register fragS *fragP;
+ register segT add_symbol_segment = SEG_ABSOLUTE;
+
+
+ for ( ; fixP; fixP = fixP->fx_next)
+ {
+ fragP = fixP->fx_frag;
+ know(fragP);
+ where = fixP->fx_where;
+ place = fragP->fr_literal + where;
+ size = fixP->fx_size;
+ add_symbolP = fixP->fx_addsy;
#ifdef TC_I960
- if (fixP->fx_callj && TC_S_IS_CALLNAME(add_symbolP)) {
- /* Relocation should be done via the
- associated 'bal' entry point
- symbol. */
-
- if (!TC_S_IS_BALNAME(tc_get_bal_of_call(add_symbolP))) {
- as_bad("No 'bal' entry point for leafproc %s",
- S_GET_NAME(add_symbolP));
- continue;
- }
- fixP->fx_addsy = add_symbolP = tc_get_bal_of_call(add_symbolP);
- } /* callj relocation */
+ if (fixP->fx_callj && TC_S_IS_CALLNAME(add_symbolP)) {
+ /* Relocation should be done via the
+ associated 'bal' entry point
+ symbol. */
+
+ if (!TC_S_IS_BALNAME(tc_get_bal_of_call(add_symbolP))) {
+ as_bad("No 'bal' entry point for leafproc %s",
+ S_GET_NAME(add_symbolP));
+ continue;
+ }
+ fixP->fx_addsy = add_symbolP = tc_get_bal_of_call(add_symbolP);
+ } /* callj relocation */
#endif
- sub_symbolP = fixP->fx_subsy;
- add_number = fixP->fx_offset;
- pcrel = fixP->fx_pcrel;
-
- if (add_symbolP) {
- add_symbol_segment = S_GET_SEGMENT(add_symbolP);
- } /* if there is an addend */
-
- if (sub_symbolP) {
- if (!add_symbolP) {
- /* Its just -sym */
- if (S_GET_SEGMENT(sub_symbolP) != SEG_ABSOLUTE) {
- as_bad("Negative of non-absolute symbol %s", S_GET_NAME(sub_symbolP));
- } /* not absolute */
-
- add_number -= S_GET_VALUE(sub_symbolP);
-
- /* if sub_symbol is in the same segment that add_symbol
- and add_symbol is either in DATA, TEXT, BSS or ABSOLUTE */
- } else if ((S_GET_SEGMENT(sub_symbolP) == add_symbol_segment)
- && (SEG_NORMAL(add_symbol_segment)
- || (add_symbol_segment == SEG_ABSOLUTE))) {
- /* Difference of 2 symbols from same segment. */
- /* Can't make difference of 2 undefineds: 'value' means */
- /* something different for N_UNDF. */
+ sub_symbolP = fixP->fx_subsy;
+ add_number = fixP->fx_offset;
+ pcrel = fixP->fx_pcrel;
+
+ if (add_symbolP) {
+ add_symbol_segment = S_GET_SEGMENT(add_symbolP);
+ } /* if there is an addend */
+
+ if (sub_symbolP) {
+ if (!add_symbolP) {
+ /* Its just -sym */
+ if (S_GET_SEGMENT(sub_symbolP) != SEG_ABSOLUTE) {
+ as_bad("Negative of non-absolute symbol %s", S_GET_NAME(sub_symbolP));
+ } /* not absolute */
+
+ add_number -= S_GET_VALUE(sub_symbolP);
+
+ /* if sub_symbol is in the same segment that add_symbol
+ and add_symbol is either in DATA, TEXT, BSS or ABSOLUTE */
+ } else if ((S_GET_SEGMENT(sub_symbolP) == add_symbol_segment)
+ && (SEG_NORMAL(add_symbol_segment)
+ || (add_symbol_segment == SEG_ABSOLUTE))) {
+ /* Difference of 2 symbols from same segment. */
+ /* Can't make difference of 2 undefineds: 'value' means */
+ /* something different for N_UNDF. */
#ifdef TC_I960
- /* Makes no sense to use the difference of 2 arbitrary symbols
- * as the target of a call instruction.
- */
- if (fixP->fx_callj) {
- as_bad("callj to difference of 2 symbols");
- }
+ /* Makes no sense to use the difference of 2 arbitrary symbols
+ * as the target of a call instruction.
+ */
+ if (fixP->fx_callj) {
+ as_bad("callj to difference of 2 symbols");
+ }
#endif /* TC_I960 */
- add_number += S_GET_VALUE(add_symbolP) -
- S_GET_VALUE(sub_symbolP);
-
- add_symbolP = NULL;
- fixP->fx_addsy = NULL;
- } else {
- /* Different segments in subtraction. */
- know(!(S_IS_EXTERNAL(sub_symbolP) && (S_GET_SEGMENT(sub_symbolP) == SEG_ABSOLUTE)));
-
- if ((S_GET_SEGMENT(sub_symbolP) == SEG_ABSOLUTE)) {
- add_number -= S_GET_VALUE(sub_symbolP);
+ add_number += S_GET_VALUE(add_symbolP) -
+ S_GET_VALUE(sub_symbolP);
+
+ add_symbolP = NULL;
+ fixP->fx_addsy = NULL;
+ } else {
+ /* Different segments in subtraction. */
+ know(!(S_IS_EXTERNAL(sub_symbolP) && (S_GET_SEGMENT(sub_symbolP) == SEG_ABSOLUTE)));
+
+ if ((S_GET_SEGMENT(sub_symbolP) == SEG_ABSOLUTE)) {
+ add_number -= S_GET_VALUE(sub_symbolP);
} else {
as_bad("Can't emit reloc {- %s-seg symbol \"%s\"} @ file address %d.",
segment_name(S_GET_SEGMENT(sub_symbolP)),
S_GET_NAME(sub_symbolP), fragP->fr_address + where);
- } /* if absolute */
+ } /* if absolute */
}
- } /* if sub_symbolP */
-
- if (add_symbolP) {
- if (add_symbol_segment == this_segment_type && pcrel) {
- /*
- * This fixup was made when the symbol's segment was
- * SEG_UNKNOWN, but it is now in the local segment.
- * So we know how to do the address without relocation.
- */
+ } /* if sub_symbolP */
+
+ if (add_symbolP) {
+ if (add_symbol_segment == this_segment_type && pcrel) {
+ /*
+ * This fixup was made when the symbol's segment was
+ * SEG_UNKNOWN, but it is now in the local segment.
+ * So we know how to do the address without relocation.
+ */
#ifdef TC_I960
- /* reloc_callj() may replace a 'call' with a 'calls' or a 'bal',
- * in which cases it modifies *fixP as appropriate. In the case
- * of a 'calls', no further work is required, and *fixP has been
- * set up to make the rest of the code below a no-op.
- */
- reloc_callj(fixP);
+ /* reloc_callj() may replace a 'call' with a 'calls' or a 'bal',
+ * in which cases it modifies *fixP as appropriate. In the case
+ * of a 'calls', no further work is required, and *fixP has been
+ * set up to make the rest of the code below a no-op.
+ */
+ reloc_callj(fixP);
#endif /* TC_I960 */
-
- add_number += S_GET_VALUE(add_symbolP);
- add_number -= md_pcrel_from (fixP);
- pcrel = 0; /* Lie. Don't want further pcrel processing. */
- fixP->fx_addsy = NULL; /* No relocations please. */
- } else
- {
- switch (add_symbol_segment)
- {
- case SEG_ABSOLUTE:
+
+ add_number += S_GET_VALUE(add_symbolP);
+ add_number -= md_pcrel_from (fixP);
+ pcrel = 0; /* Lie. Don't want further pcrel processing. */
+ fixP->fx_addsy = NULL; /* No relocations please. */
+ } else
+ {
+ switch (add_symbol_segment)
+ {
+ case SEG_ABSOLUTE:
#ifdef TC_I960
- reloc_callj(fixP); /* See comment about reloc_callj() above*/
+ reloc_callj(fixP); /* See comment about reloc_callj() above*/
#endif /* TC_I960 */
- add_number += S_GET_VALUE(add_symbolP);
- fixP->fx_addsy = NULL;
- add_symbolP = NULL;
- break;
- default:
-
- add_number += S_GET_VALUE(add_symbolP) +
- segment_info[S_GET_SEGMENT(add_symbolP)].scnhdr.s_paddr ;
- break;
-
- case SEG_UNKNOWN:
+ add_number += S_GET_VALUE(add_symbolP);
+ fixP->fx_addsy = NULL;
+ add_symbolP = NULL;
+ break;
+ default:
+
+ add_number += S_GET_VALUE(add_symbolP) +
+ segment_info[S_GET_SEGMENT(add_symbolP)].scnhdr.s_paddr ;
+ break;
+
+ case SEG_UNKNOWN:
#ifdef TC_I960
- if ((int)fixP->fx_bit_fixP == 13) {
- /* This is a COBR instruction. They have only a
- * 13-bit displacement and are only to be used
- * for local branches: flag as error, don't generate
- * relocation.
- */
- as_bad("can't use COBR format with external label");
- fixP->fx_addsy = NULL; /* No relocations please. */
- continue;
- } /* COBR */
+ if ((int)fixP->fx_bit_fixP == 13) {
+ /* This is a COBR instruction. They have only a
+ * 13-bit displacement and are only to be used
+ * for local branches: flag as error, don't generate
+ * relocation.
+ */
+ as_bad("can't use COBR format with external label");
+ fixP->fx_addsy = NULL; /* No relocations please. */
+ continue;
+ } /* COBR */
#endif /* TC_I960 */
-
-
-
- break;
-
-
- } /* switch on symbol seg */
- } /* if not in local seg */
- } /* if there was a + symbol */
-
- if (pcrel) {
- add_number -= md_pcrel_from(fixP);
- if (add_symbolP == 0) {
- fixP->fx_addsy = & abs_symbol;
- } /* if there's an add_symbol */
- } /* if pcrel */
-
- if (!fixP->fx_bit_fixP) {
- if ((size==1 &&
- (add_number& ~0xFF) && (add_number&~0xFF!=(-1&~0xFF))) ||
- (size==2 &&
- (add_number& ~0xFFFF) && (add_number&~0xFFFF!=(-1&~0xFFFF)))) {
- as_bad("Value of %d too large for field of %d bytes at 0x%x",
- add_number, size, fragP->fr_address + where);
- } /* generic error checking */
- } /* not a bit fix */
- /* once this fix has been applied, we don't have to output anything
- nothing more need be done -*/
- md_apply_fix(fixP, add_number);
-
- } /* For each fixS in this segment. */
-
-
-} /* fixup_segment() */
+
+
+
+ break;
+
+
+ } /* switch on symbol seg */
+ } /* if not in local seg */
+ } /* if there was a + symbol */
+
+ if (pcrel) {
+ add_number -= md_pcrel_from(fixP);
+ if (add_symbolP == 0) {
+ fixP->fx_addsy = & abs_symbol;
+ } /* if there's an add_symbol */
+ } /* if pcrel */
+
+ if (!fixP->fx_bit_fixP) {
+ if ((size==1 &&
+ (add_number& ~0xFF) && (add_number&~0xFF!=(-1&~0xFF))) ||
+ (size==2 &&
+ (add_number& ~0xFFFF) && (add_number&~0xFFFF!=(-1&~0xFFFF)))) {
+ as_bad("Value of %d too large for field of %d bytes at 0x%x",
+ add_number, size, fragP->fr_address + where);
+ } /* generic error checking */
+ } /* not a bit fix */
+ /* once this fix has been applied, we don't have to output anything
+ nothing more need be done -*/
+ md_apply_fix(fixP, add_number);
+
+ } /* For each fixS in this segment. */
+
+
+} /* fixup_segment() */
#endif
-/*
- * Local Variables:
- * fill-column: 131
- * End:
- */
-/* end of obj-coffbfd.c */
+
+
diff --git a/gas/config/obj-coffbfd.h b/gas/config/obj-coffbfd.h
index d1afabb..b7eef37 100644
--- a/gas/config/obj-coffbfd.h
+++ b/gas/config/obj-coffbfd.h
@@ -40,6 +40,20 @@
#elif defined(TC_A29K)
#include "coff/a29k.h"
#define TARGET_FORMAT "coff-a29k-big"
+
+/* Allow translate from aout relocs to coff relocs */
+#define NO_RELOC 20
+#define RELOC_32 1
+#define RELOC_8 2
+#define RELOC_CONST 3
+#define RELOC_CONSTH 4
+#define RELOC_JUMPTARG 5
+#define RELOC_BASE22 6
+#define RELOC_HI22 7
+#define RELOC_LO10 8
+#define RELOC_BASE13 9
+#define RELOC_WDISP22 10
+#define RELOC_WDISP30 11
#else
help me
#endif
diff --git a/gas/config/tc-a29k.c b/gas/config/tc-a29k.c
index fbdadb5..62b5063 100644
--- a/gas/config/tc-a29k.c
+++ b/gas/config/tc-a29k.c
@@ -48,7 +48,10 @@ struct machine_it {
expressionS exp;
int pcrel;
int reloc_offset; /* Offset of reloc within insn */
- enum reloc_type reloc;
+
+ int reloc;
+
+
} the_insn;
#if __STDC__ == 1
@@ -861,10 +864,6 @@ short tc_coff_fix2rtype(fixP)
fixS *fixP;
{
- /* FIXME-NOW: relocation type handling is not yet written for
- a29k. */
-
-
switch (fixP->fx_r_type) {
case RELOC_32: return(R_WORD);
case RELOC_8: return(R_BYTE);
diff --git a/gas/config/tc-a29k.h b/gas/config/tc-a29k.h
index 023a4ff..d710a70 100644
--- a/gas/config/tc-a29k.h
+++ b/gas/config/tc-a29k.h
@@ -1,38 +1,42 @@
/* tc-a29k.h -- Assemble for the AMD 29000.
- Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc.
-
- This file is part of GAS, the GNU Assembler.
-
- GAS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- GAS is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- 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. */
+ Copyright (C) 1989, 1990, 1991 Free Software Foundation, Inc.
+
+This file is part of GAS, the GNU Assembler.
+
+GAS is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GAS is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+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. */
+
+/* $Id$ */
#define TC_A29K
-#define tc_aout_pre_write_hook(x) {;} /* not used */
-#define tc_coff_symbol_emit_hook(a) {;} /* not used */
-#define tc_crawl_symbol_chain(a) {;} /* not used */
-#define tc_headers_hook(a) {;} /* not used */
+#define tc_headers_hook(a) ; /* not used */
+#define tc_headers_hook(a) ; /* not used */
+#define tc_crawl_symbol_chain(a) ; /* not used */
+#define tc_coff_symbol_emit_hook(a) ; /* not used */
#define AOUT_MACHTYPE 101
#define TC_COFF_FIX2RTYPE(fix_ptr) tc_coff_fix2rtype(fix_ptr)
#define BFD_ARCH bfd_arch_a29k
#define COFF_MAGIC SIPFBOMAGIC
-
/* Should the reloc be output ?
- on the 29k, this is true only if there is a symbol attatched.
- on the h8, this is allways true, since no fixup is done
- */
+ on the 29k, this is true only if there is a symbol attatched.
+ on the h8, this is allways true, since no fixup is done
+*/
#define TC_COUNT_RELOC(x) (x->fx_addsy)
-
/* end of tc-a29k.h */
+
+#define COFF_FLAGS F_AR32W
+#define reloc_type int
+
diff --git a/gas/expr.c b/gas/expr.c
index 601feaf..c3bd0b7 100644
--- a/gas/expr.c
+++ b/gas/expr.c
@@ -1,5 +1,5 @@
/* expr.c -operands, expressions-
- Copyright (C) 1987, 1990, 1991 Free Software Foundation, Inc.
+ Copyright (C) 1987, 1990, 1991, 1992 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
@@ -31,11 +31,11 @@
#include "obstack.h"
-#ifdef __STDC__
+#if __STDC__ == 1
static void clean_up_expression(expressionS *expressionP);
#else /* __STDC__ */
static void clean_up_expression(); /* Internal. */
-#endif /* __STDC__ */
+#endif /* not __STDC__ */
extern const char EXP_CHARS[]; /* JF hide MD floating pt stuff all the same place */
extern const char FLT_CHARS[];
@@ -67,6 +67,257 @@ FLONUM_TYPE generic_floating_point_number =
/* If nonzero, we've been asked to assemble nan, +inf or -inf */
int generic_floating_point_magic;
+floating_constant(expressionP)
+expressionS *expressionP;
+{
+ /* input_line_pointer->*/
+ /* floating-point constant. */
+ int error_code;
+
+ error_code = atof_generic
+ (& input_line_pointer, ".", EXP_CHARS,
+ & generic_floating_point_number);
+
+ if (error_code)
+ {
+ if (error_code == ERROR_EXPONENT_OVERFLOW)
+ {
+ as_bad("bad floating-point constant: exponent overflow, probably assembling junk");
+ }
+ else
+ {
+ as_bad("bad floating-point constant: unknown error code=%d.", error_code);
+ }
+ }
+ expressionP->X_seg = SEG_BIG;
+ /* input_line_pointer->just after constant, */
+ /* which may point to whitespace. */
+ expressionP->X_add_number =-1;
+
+}
+
+
+
+integer_constant(radix, expressionP)
+int radix;
+expressionS *expressionP;
+
+
+{
+ register char * digit_2; /*->2nd digit of number. */
+ char c;
+
+ register valueT number; /* offset or (absolute) value */
+ register short int digit; /* value of next digit in current radix */
+ register short int maxdig = 0; /* highest permitted digit value. */
+ register int too_many_digits = 0; /* if we see >= this number of */
+ register char *name; /* points to name of symbol */
+ register symbolS * symbolP; /* points to symbol */
+
+ int small; /* true if fits in 32 bits. */
+ extern char hex_value[]; /* in hex_value.c */
+
+ /* may be bignum, or may fit in 32 bits. */
+ /*
+ * most numbers fit into 32 bits, and we want this case to be fast.
+ * so we pretend it will fit into 32 bits. if, after making up a 32
+ * bit number, we realise that we have scanned more digits than
+ * comfortably fit into 32 bits, we re-scan the digits coding
+ * them into a bignum. for decimal and octal numbers we are conservative: some
+ * numbers may be assumed bignums when in fact they do fit into 32 bits.
+ * numbers of any radix can have excess leading zeros: we strive
+ * to recognise this and cast them back into 32 bits.
+ * we must check that the bignum really is more than 32
+ * bits, and change it back to a 32-bit number if it fits.
+ * the number we are looking for is expected to be positive, but
+ * if it fits into 32 bits as an unsigned number, we let it be a 32-bit
+ * number. the cavalier approach is for speed in ordinary cases.
+ */
+
+ switch (radix)
+ {
+
+ case 2:
+ maxdig = 2;
+ too_many_digits = 33;
+ break;
+ case 8:
+ maxdig = radix = 8;
+ too_many_digits = 11;
+ break;
+ case 16:
+
+
+ maxdig = radix = 16;
+ too_many_digits = 9;
+ break;
+ case 10:
+ maxdig = radix = 10;
+ too_many_digits = 11;
+ }
+ c = *input_line_pointer;
+ input_line_pointer++;
+ digit_2 = input_line_pointer;
+ for (number=0; (digit=hex_value[c])<maxdig; c = * input_line_pointer ++)
+ {
+ number = number * radix + digit;
+ }
+ /* c contains character after number. */
+ /* input_line_pointer->char after c. */
+ small = input_line_pointer - digit_2 < too_many_digits;
+ if (! small)
+ {
+ /*
+ * we saw a lot of digits. manufacture a bignum the hard way.
+ */
+ LITTLENUM_TYPE * leader; /*->high order littlenum of the bignum. */
+ LITTLENUM_TYPE * pointer; /*->littlenum we are frobbing now. */
+ long carry;
+
+ leader = generic_bignum;
+ generic_bignum [0] = 0;
+ generic_bignum [1] = 0;
+ /* we could just use digit_2, but lets be mnemonic. */
+ input_line_pointer = -- digit_2; /*->1st digit. */
+ c = *input_line_pointer ++;
+ for (; (carry = hex_value [c]) < maxdig; c = * input_line_pointer ++)
+ {
+ for (pointer = generic_bignum;
+ pointer <= leader;
+ pointer ++)
+ {
+ long work;
+
+ work = carry + radix * * pointer;
+ * pointer = work & LITTLENUM_MASK;
+ carry = work >> LITTLENUM_NUMBER_OF_BITS;
+ }
+ if (carry)
+ {
+ if (leader < generic_bignum + SIZE_OF_LARGE_NUMBER - 1)
+ { /* room to grow a longer bignum. */
+ * ++ leader = carry;
+ }
+ }
+ }
+ /* again, c is char after number, */
+ /* input_line_pointer->after c. */
+ know(sizeof (int) * 8 == 32);
+ know(LITTLENUM_NUMBER_OF_BITS == 16);
+ /* hence the constant "2" in the next line. */
+ if (leader < generic_bignum + 2)
+ { /* will fit into 32 bits. */
+ number =
+ ((generic_bignum [1] & LITTLENUM_MASK) << LITTLENUM_NUMBER_OF_BITS)
+ | (generic_bignum [0] & LITTLENUM_MASK);
+ small = 1;
+ }
+ else
+ {
+ number = leader - generic_bignum + 1; /* number of littlenums in the bignum. */
+ }
+ }
+ if (small)
+ {
+ /*
+ * here with number, in correct radix. c is the next char.
+ * note that unlike un*x, we allow "011f" "0x9f" to
+ * both mean the same as the (conventional) "9f". this is simply easier
+ * than checking for strict canonical form. syntax sux!
+ */
+ if (number<10)
+ {
+ if (0
+#ifdef local_labels_fb
+ || c=='b'
+#endif
+#ifdef local_labels_dollar
+ || (c=='$' && local_label_defined[number])
+#endif
+ )
+ {
+ /*
+ * backward ref to local label.
+ * because it is backward, expect it to be defined.
+ */
+ /*
+ * construct a local label.
+ */
+ name = local_label_name ((int)number, 0);
+ if (((symbolP = symbol_find(name)) != NULL) /* seen before */
+ && (S_IS_DEFINED(symbolP))) /* symbol is defined: ok */
+ { /* expected path: symbol defined. */
+ /* local labels are never absolute. don't waste time checking absoluteness. */
+ know(SEG_NORMAL(S_GET_SEGMENT(symbolP)));
+
+ expressionP->X_add_symbol = symbolP;
+ expressionP->X_add_number = 0;
+ expressionP->X_seg = S_GET_SEGMENT(symbolP);
+ }
+ else
+ { /* either not seen or not defined. */
+ as_bad("backw. ref to unknown label \"%d:\", 0 assumed.",
+ number);
+ expressionP->X_add_number = 0;
+ expressionP->X_seg = SEG_ABSOLUTE;
+ }
+ }
+ else
+ {
+ if (0
+#ifdef local_labels_fb
+ || c == 'f'
+#endif
+#ifdef local_labels_dollar
+ || (c=='$' && !local_label_defined[number])
+#endif
+ )
+ {
+ /*
+ * forward reference. expect symbol to be undefined or
+ * unknown. undefined: seen it before. unknown: never seen
+ * it in this pass.
+ * construct a local label name, then an undefined symbol.
+ * don't create a xseg frag for it: caller may do that.
+ * just return it as never seen before.
+ */
+ name = local_label_name((int)number, 1);
+ symbolP = symbol_find_or_make(name);
+ /* we have no need to check symbol properties. */
+#ifndef many_segments
+ /* since "know" puts its arg into a "string", we
+ can't have newlines in the argument. */
+ know(S_GET_SEGMENT(symbolP) == SEG_UNKNOWN || S_GET_SEGMENT(symbolP) == SEG_TEXT || S_GET_SEGMENT(symbolP) == SEG_DATA);
+#endif
+ expressionP->X_add_symbol = symbolP;
+ expressionP->X_seg = SEG_UNKNOWN;
+ expressionP->X_subtract_symbol = NULL;
+ expressionP->X_add_number = 0;
+ }
+ else
+ { /* really a number, not a local label. */
+ expressionP->X_add_number = number;
+ expressionP->X_seg = SEG_ABSOLUTE;
+ input_line_pointer --; /* restore following character. */
+ } /* if (c=='f') */
+ } /* if (c=='b') */
+ }
+ else
+ { /* really a number. */
+ expressionP->X_add_number = number;
+ expressionP->X_seg = SEG_ABSOLUTE;
+ input_line_pointer --; /* restore following character. */
+ } /* if (number<10) */
+ }
+ else
+ {
+ expressionP->X_add_number = number;
+ expressionP->X_seg = SEG_BIG;
+ input_line_pointer --; /*->char following number. */
+ } /* if (small) */
+}
+
+
/*
* Summary of operand().
*
@@ -80,390 +331,280 @@ int generic_floating_point_magic;
*
*/
+
+
static segT
- operand (expressionP)
-register expressionS * expressionP;
+operand (expressionP)
+ register expressionS * expressionP;
{
- register char c;
- register char *name; /* points to name of symbol */
- register symbolS * symbolP; /* Points to symbol */
-
- extern char hex_value[]; /* In hex_value.c */
+ register char c;
+ register symbolS * symbolP; /* points to symbol */
+ register char *name; /* points to name of symbol */
+ /* invented for humans only, hope */
+ /* optimising compiler flushes it! */
+ register short int radix; /* 2, 8, 10 or 16, 0 when floating */
+ /* 0 means we saw start of a floating- */
+ /* point constant. */
+
+ /* digits, assume it is a bignum. */
+
+
+
+
+ SKIP_WHITESPACE(); /* leading whitespace is part of operand. */
+ c = * input_line_pointer ++; /* input_line_pointer->past char in c. */
+
+ switch (c)
+ {
+#ifdef MRI
+ case '%':
+ integer_constant(2, expressionP);
+ break;
+ case '@':
+ integer_constant(8, expressionP);
+ break;
+ case '$':
+ integer_constant(16, expressionP);
+ break;
+#endif
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ input_line_pointer--;
- SKIP_WHITESPACE(); /* Leading whitespace is part of operand. */
- c = * input_line_pointer ++; /* Input_line_pointer->past char in c. */
- if (isdigit(c) || (c == 'H' && input_line_pointer[0] == '\''))
+ integer_constant(10, expressionP);
+ break;
+
+ case '0':
+ /* non-decimal radix */
+
+
+ c = *input_line_pointer;
+ switch (c)
{
- register valueT number; /* offset or (absolute) value */
- register short int digit; /* value of next digit in current radix */
- /* invented for humans only, hope */
- /* optimising compiler flushes it! */
- register short int radix; /* 2, 8, 10 or 16 */
- /* 0 means we saw start of a floating- */
- /* point constant. */
- register short int maxdig = 0;/* Highest permitted digit value. */
- register int too_many_digits = 0; /* If we see >= this number of */
- /* digits, assume it is a bignum. */
- register char * digit_2; /*->2nd digit of number. */
- int small; /* TRUE if fits in 32 bits. */
-
-
- if (c == 'H' || c == '0') { /* non-decimal radix */
- if ((c = *input_line_pointer ++)=='x' || c=='X' || c=='\'') {
- c = *input_line_pointer ++; /* read past "0x" or "0X" or H' */
- maxdig = radix = 16;
- too_many_digits = 9;
- } else {
- /* If it says '0f' and the line ends or it DOESN'T look like
- a floating point #, its a local label ref. DTRT */
- /* likewise for the b's. xoxorich. */
- if ((c == 'f' || c == 'b' || c == 'B')
- && (!*input_line_pointer ||
- (!strchr("+-.0123456789",*input_line_pointer) &&
- !strchr(EXP_CHARS,*input_line_pointer)))) {
- maxdig = radix = 10;
- too_many_digits = 11;
- c = '0';
- input_line_pointer -= 2;
-
- } else if (c == 'b' || c == 'B') {
- c = *input_line_pointer++;
- maxdig = radix = 2;
- too_many_digits = 33;
-
- } else if (c && strchr(FLT_CHARS,c)) {
- radix = 0; /* Start of floating-point constant. */
- /* input_line_pointer->1st char of number. */
- expressionP->X_add_number = -(isupper(c) ? tolower(c) : c);
-
- } else { /* By elimination, assume octal radix. */
- radix = maxdig = 8;
- too_many_digits = 11;
- }
- } /* c == char after "0" or "0x" or "0X" or "0e" etc. */
- } else {
- maxdig = radix = 10;
- too_many_digits = 11;
- } /* if operand starts with a zero */
-
- if (radix) { /* Fixed-point integer constant. */
- /* May be bignum, or may fit in 32 bits. */
- /*
- * Most numbers fit into 32 bits, and we want this case to be fast.
- * So we pretend it will fit into 32 bits. If, after making up a 32
- * bit number, we realise that we have scanned more digits than
- * comfortably fit into 32 bits, we re-scan the digits coding
- * them into a bignum. For decimal and octal numbers we are conservative: some
- * numbers may be assumed bignums when in fact they do fit into 32 bits.
- * Numbers of any radix can have excess leading zeros: we strive
- * to recognise this and cast them back into 32 bits.
- * We must check that the bignum really is more than 32
- * bits, and change it back to a 32-bit number if it fits.
- * The number we are looking for is expected to be positive, but
- * if it fits into 32 bits as an unsigned number, we let it be a 32-bit
- * number. The cavalier approach is for speed in ordinary cases.
- */
- digit_2 = input_line_pointer;
- for (number=0; (digit=hex_value[c])<maxdig; c = * input_line_pointer ++)
- {
- number = number * radix + digit;
- }
- /* C contains character after number. */
- /* Input_line_pointer->char after C. */
- small = input_line_pointer - digit_2 < too_many_digits;
- if (! small)
- {
- /*
- * We saw a lot of digits. Manufacture a bignum the hard way.
- */
- LITTLENUM_TYPE * leader; /*->high order littlenum of the bignum. */
- LITTLENUM_TYPE * pointer; /*->littlenum we are frobbing now. */
- long carry;
-
- leader = generic_bignum;
- generic_bignum [0] = 0;
- generic_bignum [1] = 0;
- /* We could just use digit_2, but lets be mnemonic. */
- input_line_pointer = -- digit_2; /*->1st digit. */
- c = *input_line_pointer ++;
- for (; (carry = hex_value [c]) < maxdig; c = * input_line_pointer ++)
- {
- for (pointer = generic_bignum;
- pointer <= leader;
- pointer ++)
- {
- long work;
-
- work = carry + radix * * pointer;
- * pointer = work & LITTLENUM_MASK;
- carry = work >> LITTLENUM_NUMBER_OF_BITS;
- }
- if (carry)
- {
- if (leader < generic_bignum + SIZE_OF_LARGE_NUMBER - 1)
- { /* Room to grow a longer bignum. */
- * ++ leader = carry;
- }
- }
- }
- /* Again, C is char after number, */
- /* input_line_pointer->after C. */
- know(sizeof (int) * 8 == 32);
- know(LITTLENUM_NUMBER_OF_BITS == 16);
- /* Hence the constant "2" in the next line. */
- if (leader < generic_bignum + 2)
- { /* Will fit into 32 bits. */
- number =
- ((generic_bignum [1] & LITTLENUM_MASK) << LITTLENUM_NUMBER_OF_BITS)
- | (generic_bignum [0] & LITTLENUM_MASK);
- small = 1;
- }
- else
- {
- number = leader - generic_bignum + 1; /* Number of littlenums in the bignum. */
- }
- }
- if (small)
- {
- /*
- * Here with number, in correct radix. c is the next char.
- * Note that unlike Un*x, we allow "011f" "0x9f" to
- * both mean the same as the (conventional) "9f". This is simply easier
- * than checking for strict canonical form. Syntax sux!
- */
- if (number<10)
- {
- if (0
-#ifdef LOCAL_LABELS_FB
- || c=='b'
-#endif
-#ifdef LOCAL_LABELS_DOLLAR
- || (c=='$' && local_label_defined[number])
-#endif
- )
- {
- /*
- * Backward ref to local label.
- * Because it is backward, expect it to be DEFINED.
- */
- /*
- * Construct a local label.
- */
- name = local_label_name ((int)number, 0);
- if (((symbolP = symbol_find(name)) != NULL) /* seen before */
- && (S_IS_DEFINED(symbolP))) /* symbol is defined: OK */
- { /* Expected path: symbol defined. */
- /* Local labels are never absolute. Don't waste time checking absoluteness. */
- know(SEG_NORMAL(S_GET_SEGMENT(symbolP)));
-
- expressionP->X_add_symbol = symbolP;
- expressionP->X_add_number = 0;
- expressionP->X_seg = S_GET_SEGMENT(symbolP);
- }
- else
- { /* Either not seen or not defined. */
- as_bad("Backw. ref to unknown label \"%d:\", 0 assumed.",
- number);
- expressionP->X_add_number = 0;
- expressionP->X_seg = SEG_ABSOLUTE;
- }
- }
- else
- {
- if (0
-#ifdef LOCAL_LABELS_FB
- || c == 'f'
-#endif
-#ifdef LOCAL_LABELS_DOLLAR
- || (c=='$' && !local_label_defined[number])
-#endif
- )
- {
- /*
- * Forward reference. Expect symbol to be undefined or
- * unknown. Undefined: seen it before. Unknown: never seen
- * it in this pass.
- * Construct a local label name, then an undefined symbol.
- * Don't create a XSEG frag for it: caller may do that.
- * Just return it as never seen before.
- */
- name = local_label_name((int)number, 1);
- symbolP = symbol_find_or_make(name);
- /* We have no need to check symbol properties. */
-#ifndef MANY_SEGMENTS
- /* Since "know" puts its arg into a "string", we
- can't have newlines in the argument. */
- know(S_GET_SEGMENT(symbolP) == SEG_UNKNOWN || S_GET_SEGMENT(symbolP) == SEG_TEXT || S_GET_SEGMENT(symbolP) == SEG_DATA);
-#endif
- expressionP->X_add_symbol = symbolP;
- expressionP->X_seg = SEG_UNKNOWN;
- expressionP->X_subtract_symbol = NULL;
- expressionP->X_add_number = 0;
- }
- else
- { /* Really a number, not a local label. */
- expressionP->X_add_number = number;
- expressionP->X_seg = SEG_ABSOLUTE;
- input_line_pointer --; /* Restore following character. */
- } /* if (c=='f') */
- } /* if (c=='b') */
- }
- else
- { /* Really a number. */
- expressionP->X_add_number = number;
- expressionP->X_seg = SEG_ABSOLUTE;
- input_line_pointer --; /* Restore following character. */
- } /* if (number<10) */
- }
- else
- {
- expressionP->X_add_number = number;
- expressionP->X_seg = SEG_BIG;
- input_line_pointer --; /*->char following number. */
- } /* if (small) */
- } /* (If integer constant) */
- else
- { /* input_line_pointer->*/
- /* floating-point constant. */
- int error_code;
-
- error_code = atof_generic
- (& input_line_pointer, ".", EXP_CHARS,
- & generic_floating_point_number);
-
- if (error_code)
- {
- if (error_code == ERROR_EXPONENT_OVERFLOW)
- {
- as_bad("Bad floating-point constant: exponent overflow, probably assembling junk");
- }
- else
- {
- as_bad("Bad floating-point constant: unknown error code=%d.", error_code);
- }
- }
- expressionP->X_seg = SEG_BIG;
- /* input_line_pointer->just after constant, */
- /* which may point to whitespace. */
- know(expressionP->X_add_number < 0); /* < 0 means "floating point". */
- } /* if (not floating-point constant) */
+
+ default:
+ /* The string was only zero */
+ expressionP->X_add_symbol = 0;
+ expressionP->X_add_number = 0;
+ expressionP->X_seg = SEG_ABSOLUTE;
+ break;
+
+ case 'x':
+ case 'X':
+ input_line_pointer++;
+ integer_constant(16, expressionP);
+ break;
+ case 'B':
+ case 'b':
+ input_line_pointer++;
+ integer_constant(2, expressionP);
+ break;
+
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ integer_constant(8, expressionP);
+ break;
+
+ case 'f':
+ /* if it says '0f' and the line ends or it doesn't look like
+ a floating point #, its a local label ref. dtrt */
+ /* likewise for the b's. xoxorich. */
+ if ((c == 'f' || c == 'b' || c == 'b')
+ && (!*input_line_pointer ||
+ (!strchr("+-.0123456789",*input_line_pointer) &&
+ !strchr(EXP_CHARS,*input_line_pointer))))
+ {
+ input_line_pointer -= 2;
+ integer_constant(10, expressionP);
+ break;
+ }
+
+ case 'd':
+ case 'D':
+ case 'F':
+
+ case 'e':
+ case 'E':
+ case 'g':
+ case 'G':
+
+ input_line_pointer++;
+ floating_constant(expressionP);
+ break;
}
- else if(c=='.' && !is_part_of_name(*input_line_pointer)) {
- extern struct obstack frags;
-
- /*
- JF: '.' is pseudo symbol with value of current location in current
- segment. . .
- */
- symbolP = symbol_new("L0\001",
- now_seg,
- (valueT)(obstack_next_free(&frags)-frag_now->fr_literal),
- frag_now);
-
- expressionP->X_add_number=0;
- expressionP->X_add_symbol=symbolP;
- expressionP->X_seg = now_seg;
-
- } else if (is_name_beginner(c)) /* here if did not begin with a digit */
+
+ break;
+ case '(':
+ /* didn't begin with digit & not a name */
+ {
+ (void)expression(expressionP);
+ /* Expression() will pass trailing whitespace */
+ if (* input_line_pointer ++ != ')')
{
- /*
- * Identifier begins here.
- * This is kludged for speed, so code is repeated.
- */
- name = -- input_line_pointer;
- c = get_symbol_end();
- symbolP = symbol_find_or_make(name);
- /*
- * If we have an absolute symbol or a reg, then we know its value now.
- */
- expressionP->X_seg = S_GET_SEGMENT(symbolP);
- switch (expressionP->X_seg)
+ as_bad("Missing ')' assumed");
+ input_line_pointer --;
+ }
+ /* here with input_line_pointer->char after "(...)" */
+ }
+ return;
+
+
+ case '\'':
+ /*
+ * Warning: to conform to other people's assemblers NO ESCAPEMENT is permitted
+ * for a single quote. The next character, parity errors and all, is taken
+ * as the value of the operand. VERY KINKY.
+ */
+ expressionP->X_add_number = * input_line_pointer ++;
+ expressionP->X_seg = SEG_ABSOLUTE;
+ break;
+
+ case '~':
+ case '-':
+ case '+':
+
+ {
+ /* unary operator: hope for SEG_ABSOLUTE */
+ switch(operand (expressionP)) {
+ case SEG_ABSOLUTE:
+ /* input_line_pointer -> char after operand */
+ if ( c=='-' )
{
- case SEG_ABSOLUTE:
- case SEG_REGISTER:
- expressionP->X_add_number = S_GET_VALUE(symbolP);
- break;
-
- default:
- expressionP->X_add_number = 0;
- expressionP->X_add_symbol = symbolP;
+ expressionP -> X_add_number = - expressionP -> X_add_number;
+ /*
+ * Notice: '-' may overflow: no warning is given. This is compatible
+ * with other people's assemblers. Sigh.
+ */
}
- * input_line_pointer = c;
- expressionP->X_subtract_symbol = NULL;
- }
- else if (c=='(')/* didn't begin with digit & not a name */
- {
- (void)expression(expressionP);
- /* Expression() will pass trailing whitespace */
- if (* input_line_pointer ++ != ')')
+ else
{
- as_bad("Missing ')' assumed");
- input_line_pointer --;
+ expressionP -> X_add_number = ~ expressionP -> X_add_number;
}
- /* here with input_line_pointer->char after "(...)" */
- }
- else if (c == '~' || c == '-' || c == '+') {
- /* unary operator: hope for SEG_ABSOLUTE */
- switch (operand (expressionP)) {
- case SEG_ABSOLUTE:
- /* input_line_pointer->char after operand */
- if (c=='-') {
- expressionP->X_add_number = - expressionP->X_add_number;
- /*
- * Notice: '-' may overflow: no warning is given. This is compatible
- * with other people's assemblers. Sigh.
- */
- } else if (c == '~') {
- expressionP->X_add_number = ~ expressionP->X_add_number;
- } else if (c != '+') {
- know(0);
- } /* switch on unary operator */
+ break;
+
+ case SEG_TEXT:
+ case SEG_DATA:
+ case SEG_BSS:
+ case SEG_PASS1:
+ case SEG_UNKNOWN:
+ if(c=='-') { /* JF I hope this hack works */
+ expressionP->X_subtract_symbol=expressionP->X_add_symbol;
+ expressionP->X_add_symbol=0;
+ expressionP->X_seg=SEG_DIFFERENCE;
break;
-
- default: /* unary on non-absolute is unsuported */
- if (!SEG_NORMAL(operand(expressionP)))
- {
- as_bad("Unary operator %c ignored because bad operand follows", c);
- break;
- }
- /* Fall through for normal segments ****/
- case SEG_PASS1:
- case SEG_UNKNOWN:
- if(c=='-') { /* JF I hope this hack works */
- expressionP->X_subtract_symbol=expressionP->X_add_symbol;
- expressionP->X_add_symbol=0;
- expressionP->X_seg=SEG_DIFFERENCE;
- break;
- }
- /* Expression undisturbed from operand(). */
- }
- }
- else if (c=='\'')
+ }
+ default: /* unary on non-absolute is unsuported */
+ as_warn("Unary operator %c ignored because bad operand follows", c);
+ break;
+ /* Expression undisturbed from operand(). */
+ }
+ }
+
+
+
+ break;
+
+ case '.':
+ if( !is_part_of_name(*input_line_pointer))
{
- /*
- * Warning: to conform to other people's assemblers NO ESCAPEMENT is permitted
- * for a single quote. The next character, parity errors and all, is taken
- * as the value of the operand. VERY KINKY.
- */
- expressionP->X_add_number = * input_line_pointer ++;
- expressionP->X_seg = SEG_ABSOLUTE;
+ extern struct obstack frags;
+
+ /*
+ JF: '.' is pseudo symbol with value of current location in current
+ segment. . .
+ */
+ symbolP = symbol_new("L0\001",
+ now_seg,
+ (valueT)(obstack_next_free(&frags)-frag_now->fr_literal),
+ frag_now);
+
+ expressionP->X_add_number=0;
+ expressionP->X_add_symbol=symbolP;
+ expressionP->X_seg = now_seg;
+ break;
+
}
- else
+ else
{
+ goto isname;
+
+
+ }
+
+ case '\n':
/* can't imagine any other kind of operand */
expressionP->X_seg = SEG_ABSENT;
input_line_pointer --;
md_operand (expressionP);
+ break;
+ /* Fall through */
+ default:
+ if (is_name_beginner(c)) /* here if did not begin with a digit */
+ {
+ /*
+ * Identifier begins here.
+ * This is kludged for speed, so code is repeated.
+ */
+isname:
+ name = -- input_line_pointer;
+ c = get_symbol_end();
+ symbolP = symbol_find_or_make(name);
+ /*
+ * If we have an absolute symbol or a reg, then we know its value now.
+ */
+ expressionP->X_seg = S_GET_SEGMENT(symbolP);
+ switch (expressionP->X_seg)
+ {
+ case SEG_ABSOLUTE:
+ case SEG_REGISTER:
+ expressionP->X_add_number = S_GET_VALUE(symbolP);
+ break;
+
+ default:
+ expressionP->X_add_number = 0;
+ expressionP->X_add_symbol = symbolP;
+ }
+ * input_line_pointer = c;
+ expressionP->X_subtract_symbol = NULL;
}
- /*
- * It is more 'efficient' to clean up the expressions when they are created.
- * Doing it here saves lines of code.
- */
- clean_up_expression (expressionP);
- SKIP_WHITESPACE(); /*->1st char after operand. */
- know(* input_line_pointer != ' ');
- return (expressionP->X_seg);
+ else
+ {
+ as_bad("Bad expression");
+ expressionP->X_add_number = 0;
+ expressionP->X_seg = SEG_ABSOLUTE;
+
+ }
+
+ }
+
+
+
+
+
+
+
+ /*
+ * It is more 'efficient' to clean up the expressionS when they are created.
+ * Doing it here saves lines of code.
+ */
+ clean_up_expression (expressionP);
+ SKIP_WHITESPACE(); /*->1st char after operand. */
+ know(* input_line_pointer != ' ');
+ return (expressionP->X_seg);
} /* operand() */
+
/* Internal. Simplify a struct expression for use by expr() */
@@ -479,29 +620,29 @@ register expressionS * expressionP;
*/
static void
- clean_up_expression (expressionP)
-register expressionS * expressionP;
+clean_up_expression (expressionP)
+ register expressionS * expressionP;
{
- switch (expressionP->X_seg)
- {
- case SEG_ABSENT:
- case SEG_PASS1:
+ switch (expressionP->X_seg)
+ {
+ case SEG_ABSENT:
+ case SEG_PASS1:
expressionP->X_add_symbol = NULL;
expressionP->X_subtract_symbol = NULL;
expressionP->X_add_number = 0;
break;
-
- case SEG_BIG:
- case SEG_ABSOLUTE:
+
+ case SEG_BIG:
+ case SEG_ABSOLUTE:
expressionP->X_subtract_symbol = NULL;
expressionP->X_add_symbol = NULL;
break;
-
- case SEG_UNKNOWN:
+
+ case SEG_UNKNOWN:
expressionP->X_subtract_symbol = NULL;
break;
-
- case SEG_DIFFERENCE:
+
+ case SEG_DIFFERENCE:
/*
* It does not hurt to 'cancel' NULL==NULL
* when comparing symbols for 'eq'ness.
@@ -518,21 +659,21 @@ register expressionS * expressionP;
expressionP->X_seg = SEG_ABSOLUTE;
}
break;
-
- case SEG_REGISTER:
+
+ case SEG_REGISTER:
expressionP->X_add_symbol = NULL;
expressionP->X_subtract_symbol = NULL;
break;
-
- default:
+
+ default:
if (SEG_NORMAL(expressionP->X_seg)) {
- expressionP->X_subtract_symbol = NULL;
+ expressionP->X_subtract_symbol = NULL;
}
else {
BAD_CASE (expressionP->X_seg);
}
break;
- }
+ }
} /* clean_up_expression() */
/*
@@ -547,72 +688,72 @@ register expressionS * expressionP;
*/
static segT
- expr_part (symbol_1_PP, symbol_2_P)
-symbolS ** symbol_1_PP;
-symbolS * symbol_2_P;
+expr_part (symbol_1_PP, symbol_2_P)
+ symbolS ** symbol_1_PP;
+ symbolS * symbol_2_P;
{
segT return_value;
#ifndef MANY_SEGMENTS
know((* symbol_1_PP) == NULL || (S_GET_SEGMENT(*symbol_1_PP) == SEG_TEXT) || (S_GET_SEGMENT(*symbol_1_PP) == SEG_DATA) || (S_GET_SEGMENT(*symbol_1_PP) == SEG_BSS) || (!S_IS_DEFINED(* symbol_1_PP)));
know(symbol_2_P == NULL || (S_GET_SEGMENT(symbol_2_P) == SEG_TEXT) || (S_GET_SEGMENT(symbol_2_P) == SEG_DATA) || (S_GET_SEGMENT(symbol_2_P) == SEG_BSS) || (!S_IS_DEFINED(symbol_2_P)));
#endif
- if (* symbol_1_PP)
+ if (* symbol_1_PP)
{
- if (!S_IS_DEFINED(* symbol_1_PP))
+ if (!S_IS_DEFINED(* symbol_1_PP))
{
- if (symbol_2_P)
+ if (symbol_2_P)
{
return_value = SEG_PASS1;
* symbol_1_PP = NULL;
}
- else
+ else
{
know(!S_IS_DEFINED(* symbol_1_PP));
return_value = SEG_UNKNOWN;
}
}
- else
+ else
{
- if (symbol_2_P)
+ if (symbol_2_P)
{
- if (!S_IS_DEFINED(symbol_2_P))
+ if (!S_IS_DEFINED(symbol_2_P))
{
- * symbol_1_PP = NULL;
- return_value = SEG_PASS1;
+ * symbol_1_PP = NULL;
+ return_value = SEG_PASS1;
}
- else
+ else
{
- /* {seg1} - {seg2} */
- as_bad("Expression too complex, 2 symbols forgotten: \"%s\" \"%s\"",
- S_GET_NAME(* symbol_1_PP), S_GET_NAME(symbol_2_P));
- * symbol_1_PP = NULL;
- return_value = SEG_ABSOLUTE;
+ /* {seg1} - {seg2} */
+ as_bad("Expression too complex, 2 symbolS forgotten: \"%s\" \"%s\"",
+ S_GET_NAME(* symbol_1_PP), S_GET_NAME(symbol_2_P));
+ * symbol_1_PP = NULL;
+ return_value = SEG_ABSOLUTE;
}
}
- else
+ else
{
- return_value = S_GET_SEGMENT(* symbol_1_PP);
+ return_value = S_GET_SEGMENT(* symbol_1_PP);
}
}
}
- else
+ else
{ /* (* symbol_1_PP) == NULL */
- if (symbol_2_P)
+ if (symbol_2_P)
{
- * symbol_1_PP = symbol_2_P;
- return_value = S_GET_SEGMENT(symbol_2_P);
+ * symbol_1_PP = symbol_2_P;
+ return_value = S_GET_SEGMENT(symbol_2_P);
}
- else
+ else
{
- * symbol_1_PP = NULL;
- return_value = SEG_ABSOLUTE;
+ * symbol_1_PP = NULL;
+ return_value = SEG_ABSOLUTE;
}
}
#ifndef MANY_SEGMENTS
- know(return_value == SEG_ABSOLUTE || return_value == SEG_TEXT || return_value == SEG_DATA || return_value == SEG_BSS || return_value == SEG_UNKNOWN || return_value == SEG_PASS1);
+ know(return_value == SEG_ABSOLUTE || return_value == SEG_TEXT || return_value == SEG_DATA || return_value == SEG_BSS || return_value == SEG_UNKNOWN || return_value == SEG_PASS1);
#endif
- know((*symbol_1_PP) == NULL || (S_GET_SEGMENT(*symbol_1_PP) == return_value));
- return (return_value);
+ know((*symbol_1_PP) == NULL || (S_GET_SEGMENT(*symbol_1_PP) == return_value));
+ return (return_value);
} /* expr_part() */
/* Expression parser. */
@@ -692,191 +833,191 @@ static const operatorT op_encoding [256] = { /* maps ASCII->operators */
* 3 * / % << >>
*/
static const operator_rankT
- op_rank [] = { 0, 3, 3, 3, 3, 3, 2, 2, 2, 2, 1, 1 };
+op_rank [] = { 0, 3, 3, 3, 3, 3, 2, 2, 2, 2, 1, 1 };
/* Return resultP->X_seg. */
segT expr(rank, resultP)
- register operator_rankT rank; /* Larger # is higher rank. */
- register expressionS *resultP; /* Deliver result here. */
+register operator_rankT rank; /* Larger # is higher rank. */
+register expressionS *resultP; /* Deliver result here. */
{
- expressionS right;
- register operatorT op_left;
- register char c_left; /* 1st operator character. */
- register operatorT op_right;
- register char c_right;
-
- know(rank >= 0);
- (void)operand (resultP);
- know(* input_line_pointer != ' '); /* Operand() gobbles spaces. */
- c_left = * input_line_pointer; /* Potential operator character. */
- op_left = op_encoding [c_left];
- while (op_left != O_illegal && op_rank [(int) op_left] > rank)
+ expressionS right;
+ register operatorT op_left;
+ register char c_left; /* 1st operator character. */
+ register operatorT op_right;
+ register char c_right;
+
+ know(rank >= 0);
+ (void)operand (resultP);
+ know(* input_line_pointer != ' '); /* Operand() gobbles spaces. */
+ c_left = * input_line_pointer; /* Potential operator character. */
+ op_left = op_encoding [c_left];
+ while (op_left != O_illegal && op_rank [(int) op_left] > rank)
{
- input_line_pointer ++; /*->after 1st character of operator. */
- /* Operators "<<" and ">>" have 2 characters. */
- if (* input_line_pointer == c_left && (c_left == '<' || c_left == '>'))
+ input_line_pointer ++; /*->after 1st character of operator. */
+ /* Operators "<<" and ">>" have 2 characters. */
+ if (* input_line_pointer == c_left && (c_left == '<' || c_left == '>'))
{
- input_line_pointer ++;
+ input_line_pointer ++;
} /*->after operator. */
- if (SEG_ABSENT == expr (op_rank[(int) op_left], &right))
+ if (SEG_ABSENT == expr (op_rank[(int) op_left], &right))
{
- as_warn("Missing operand value assumed absolute 0.");
- resultP->X_add_number = 0;
- resultP->X_subtract_symbol = NULL;
- resultP->X_add_symbol = NULL;
- resultP->X_seg = SEG_ABSOLUTE;
+ as_warn("Missing operand value assumed absolute 0.");
+ resultP->X_add_number = 0;
+ resultP->X_subtract_symbol = NULL;
+ resultP->X_add_symbol = NULL;
+ resultP->X_seg = SEG_ABSOLUTE;
}
- know(* input_line_pointer != ' ');
- c_right = * input_line_pointer;
- op_right = op_encoding [c_right];
- if (* input_line_pointer == c_right && (c_right == '<' || c_right == '>'))
+ know(* input_line_pointer != ' ');
+ c_right = * input_line_pointer;
+ op_right = op_encoding [c_right];
+ if (* input_line_pointer == c_right && (c_right == '<' || c_right == '>'))
{
- input_line_pointer ++;
+ input_line_pointer ++;
} /*->after operator. */
- know((int) op_right == 0 || op_rank [(int) op_right] <= op_rank[(int) op_left]);
- /* input_line_pointer->after right-hand quantity. */
- /* left-hand quantity in resultP */
- /* right-hand quantity in right. */
- /* operator in op_left. */
- if (resultP->X_seg == SEG_PASS1 || right . X_seg == SEG_PASS1)
+ know((int) op_right == 0 || op_rank [(int) op_right] <= op_rank[(int) op_left]);
+ /* input_line_pointer->after right-hand quantity. */
+ /* left-hand quantity in resultP */
+ /* right-hand quantity in right. */
+ /* operator in op_left. */
+ if (resultP->X_seg == SEG_PASS1 || right . X_seg == SEG_PASS1)
{
- resultP->X_seg = SEG_PASS1;
+ resultP->X_seg = SEG_PASS1;
}
- else
+ else
{
- if (resultP->X_seg == SEG_BIG)
+ if (resultP->X_seg == SEG_BIG)
{
- as_warn("Left operand of %c is a %s. Integer 0 assumed.",
- c_left, resultP->X_add_number > 0 ? "bignum" : "float");
- resultP->X_seg = SEG_ABSOLUTE;
- resultP->X_add_symbol = 0;
- resultP->X_subtract_symbol = 0;
- resultP->X_add_number = 0;
+ as_warn("Left operand of %c is a %s. Integer 0 assumed.",
+ c_left, resultP->X_add_number > 0 ? "bignum" : "float");
+ resultP->X_seg = SEG_ABSOLUTE;
+ resultP->X_add_symbol = 0;
+ resultP->X_subtract_symbol = 0;
+ resultP->X_add_number = 0;
}
- if (right . X_seg == SEG_BIG)
+ if (right . X_seg == SEG_BIG)
{
- as_warn("Right operand of %c is a %s. Integer 0 assumed.",
- c_left, right . X_add_number > 0 ? "bignum" : "float");
- right . X_seg = SEG_ABSOLUTE;
- right . X_add_symbol = 0;
- right . X_subtract_symbol = 0;
- right . X_add_number = 0;
+ as_warn("Right operand of %c is a %s. Integer 0 assumed.",
+ c_left, right . X_add_number > 0 ? "bignum" : "float");
+ right . X_seg = SEG_ABSOLUTE;
+ right . X_add_symbol = 0;
+ right . X_subtract_symbol = 0;
+ right . X_add_number = 0;
}
- if (op_left == O_subtract)
+ if (op_left == O_subtract)
{
- /*
- * Convert - into + by exchanging symbols and negating number.
- * I know -infinity can't be negated in 2's complement:
- * but then it can't be subtracted either. This trick
- * does not cause any further inaccuracy.
- */
-
- register symbolS * symbolP;
-
- right . X_add_number = - right . X_add_number;
- symbolP = right . X_add_symbol;
- right . X_add_symbol = right . X_subtract_symbol;
- right . X_subtract_symbol = symbolP;
- if (symbolP)
+ /*
+ * Convert - into + by exchanging symbolS and negating number.
+ * I know -infinity can't be negated in 2's complement:
+ * but then it can't be subtracted either. This trick
+ * does not cause any further inaccuracy.
+ */
+
+ register symbolS * symbolP;
+
+ right . X_add_number = - right . X_add_number;
+ symbolP = right . X_add_symbol;
+ right . X_add_symbol = right . X_subtract_symbol;
+ right . X_subtract_symbol = symbolP;
+ if (symbolP)
{
- right . X_seg = SEG_DIFFERENCE;
+ right . X_seg = SEG_DIFFERENCE;
}
- op_left = O_add;
+ op_left = O_add;
}
-
- if (op_left == O_add)
+
+ if (op_left == O_add)
{
- segT seg1;
- segT seg2;
+ segT seg1;
+ segT seg2;
#ifndef MANY_SEGMENTS
- know(resultP->X_seg == SEG_DATA || resultP->X_seg == SEG_TEXT || resultP->X_seg == SEG_BSS || resultP->X_seg == SEG_UNKNOWN || resultP->X_seg == SEG_DIFFERENCE || resultP->X_seg == SEG_ABSOLUTE || resultP->X_seg == SEG_PASS1);
- know(right.X_seg == SEG_DATA || right.X_seg == SEG_TEXT || right.X_seg == SEG_BSS || right.X_seg == SEG_UNKNOWN || right.X_seg == SEG_DIFFERENCE || right.X_seg == SEG_ABSOLUTE || right.X_seg == SEG_PASS1);
+ know(resultP->X_seg == SEG_DATA || resultP->X_seg == SEG_TEXT || resultP->X_seg == SEG_BSS || resultP->X_seg == SEG_UNKNOWN || resultP->X_seg == SEG_DIFFERENCE || resultP->X_seg == SEG_ABSOLUTE || resultP->X_seg == SEG_PASS1);
+ know(right.X_seg == SEG_DATA || right.X_seg == SEG_TEXT || right.X_seg == SEG_BSS || right.X_seg == SEG_UNKNOWN || right.X_seg == SEG_DIFFERENCE || right.X_seg == SEG_ABSOLUTE || right.X_seg == SEG_PASS1);
#endif
- clean_up_expression (& right);
- clean_up_expression (resultP);
-
- seg1 = expr_part (& resultP->X_add_symbol, right . X_add_symbol);
- seg2 = expr_part (& resultP->X_subtract_symbol, right . X_subtract_symbol);
- if (seg1 == SEG_PASS1 || seg2 == SEG_PASS1) {
- need_pass_2 = 1;
- resultP->X_seg = SEG_PASS1;
- } else if (seg2 == SEG_ABSOLUTE)
- resultP->X_seg = seg1;
- else if (seg1 != SEG_UNKNOWN
- && seg1 != SEG_ABSOLUTE
- && seg2 != SEG_UNKNOWN
- && seg1 != seg2) {
- know(seg2 != SEG_ABSOLUTE);
- know(resultP->X_subtract_symbol);
+ clean_up_expression (& right);
+ clean_up_expression (resultP);
+
+ seg1 = expr_part (& resultP->X_add_symbol, right . X_add_symbol);
+ seg2 = expr_part (& resultP->X_subtract_symbol, right . X_subtract_symbol);
+ if (seg1 == SEG_PASS1 || seg2 == SEG_PASS1) {
+ need_pass_2 = 1;
+ resultP->X_seg = SEG_PASS1;
+ } else if (seg2 == SEG_ABSOLUTE)
+ resultP->X_seg = seg1;
+ else if (seg1 != SEG_UNKNOWN
+ && seg1 != SEG_ABSOLUTE
+ && seg2 != SEG_UNKNOWN
+ && seg1 != seg2) {
+ know(seg2 != SEG_ABSOLUTE);
+ know(resultP->X_subtract_symbol);
#ifndef MANY_SEGMENTS
- know(seg1 == SEG_TEXT || seg1 == SEG_DATA || seg1== SEG_BSS);
- know(seg2 == SEG_TEXT || seg2 == SEG_DATA || seg2== SEG_BSS);
+ know(seg1 == SEG_TEXT || seg1 == SEG_DATA || seg1== SEG_BSS);
+ know(seg2 == SEG_TEXT || seg2 == SEG_DATA || seg2== SEG_BSS);
#endif
- know(resultP->X_add_symbol);
- know(resultP->X_subtract_symbol);
- as_bad("Expression too complex: forgetting %s - %s",
- S_GET_NAME(resultP->X_add_symbol),
- S_GET_NAME(resultP->X_subtract_symbol));
- resultP->X_seg = SEG_ABSOLUTE;
- /* Clean_up_expression() will do the rest. */
- } else
- resultP->X_seg = SEG_DIFFERENCE;
-
- resultP->X_add_number += right . X_add_number;
- clean_up_expression (resultP);
- }
- else
+ know(resultP->X_add_symbol);
+ know(resultP->X_subtract_symbol);
+ as_bad("Expression too complex: forgetting %s - %s",
+ S_GET_NAME(resultP->X_add_symbol),
+ S_GET_NAME(resultP->X_subtract_symbol));
+ resultP->X_seg = SEG_ABSOLUTE;
+ /* Clean_up_expression() will do the rest. */
+ } else
+ resultP->X_seg = SEG_DIFFERENCE;
+
+ resultP->X_add_number += right . X_add_number;
+ clean_up_expression (resultP);
+ }
+ else
{ /* Not +. */
- if (resultP->X_seg == SEG_UNKNOWN || right . X_seg == SEG_UNKNOWN)
+ if (resultP->X_seg == SEG_UNKNOWN || right . X_seg == SEG_UNKNOWN)
{
- resultP->X_seg = SEG_PASS1;
- need_pass_2 = 1;
+ resultP->X_seg = SEG_PASS1;
+ need_pass_2 = 1;
}
- else
+ else
{
- resultP->X_subtract_symbol = NULL;
- resultP->X_add_symbol = NULL;
- /* Will be SEG_ABSOLUTE. */
- if (resultP->X_seg != SEG_ABSOLUTE || right . X_seg != SEG_ABSOLUTE)
+ resultP->X_subtract_symbol = NULL;
+ resultP->X_add_symbol = NULL;
+ /* Will be SEG_ABSOLUTE. */
+ if (resultP->X_seg != SEG_ABSOLUTE || right . X_seg != SEG_ABSOLUTE)
{
- as_bad("Relocation error. Absolute 0 assumed.");
- resultP->X_seg = SEG_ABSOLUTE;
- resultP->X_add_number = 0;
+ as_bad("Relocation error. Absolute 0 assumed.");
+ resultP->X_seg = SEG_ABSOLUTE;
+ resultP->X_add_number = 0;
}
- else
+ else
{
- switch (op_left)
+ switch (op_left)
{
case O_bit_inclusive_or:
- resultP->X_add_number |= right . X_add_number;
- break;
-
+ resultP->X_add_number |= right . X_add_number;
+ break;
+
case O_modulus:
- if (right . X_add_number)
+ if (right . X_add_number)
{
- resultP->X_add_number %= right . X_add_number;
+ resultP->X_add_number %= right . X_add_number;
}
- else
+ else
{
- as_warn("Division by 0. 0 assumed.");
- resultP->X_add_number = 0;
+ as_warn("Division by 0. 0 assumed.");
+ resultP->X_add_number = 0;
}
- break;
-
+ break;
+
case O_bit_and:
- resultP->X_add_number &= right . X_add_number;
- break;
-
+ resultP->X_add_number &= right . X_add_number;
+ break;
+
case O_multiply:
- resultP->X_add_number *= right . X_add_number;
- break;
-
+ resultP->X_add_number *= right . X_add_number;
+ break;
+
case O_divide:
- if (right . X_add_number)
+ if (right . X_add_number)
{
- resultP->X_add_number /= right . X_add_number;
+ resultP->X_add_number /= right . X_add_number;
}
- else
+ else
{
as_warn("Division by 0. 0 assumed.");
resultP->X_add_number = 0;
diff --git a/gas/listing.c b/gas/listing.c
index 7724d91..04fef6b 100644
--- a/gas/listing.c
+++ b/gas/listing.c
@@ -1,95 +1,95 @@
/* listing.c - mainting assembly listings
Copyright (C) 1991, 1992 Free Software Foundation, Inc.
-
- This file is part of GAS, the GNU Assembler.
-
- GAS is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- GAS is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- 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. */
+
+This file is part of GAS, the GNU Assembler.
+
+GAS is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GAS is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+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. */
/*
- Contributed by Steve Chamberlain
- sac@cygnus.com
-
-
- A listing page looks like:
-
- LISTING_HEADER sourcefilename pagenumber
- TITLE LINE
- SUBTITLE LINE
- linenumber address data source
- linenumber address data source
- linenumber address data source
- linenumber address data source
-
- If not overridden, the listing commands are:
-
- .title "stuff"
- Put "stuff" onto the title line
- .sbttl "stuff"
- Put stuff onto the subtitle line
-
+ Contributed by Steve Chamberlain
+ sac@cygnus.com
+
+
+ A listing page looks like:
+
+ LISTING_HEADER sourcefilename pagenumber
+ TITLE LINE
+ SUBTITLE LINE
+ linenumber address data source
+ linenumber address data source
+ linenumber address data source
+ linenumber address data source
+
+ If not overridden, the listing commands are:
+
+ .title "stuff"
+ Put "stuff" onto the title line
+ .sbttl "stuff"
+ Put stuff onto the subtitle line
+
If these commands come within 10 lines of the top of the page, they
will affect the page they are on, as well as any subsequent page
-
- .eject
- Thow a page
- .list
- Increment the enable listing counter
- .nolist
- Decrement the enable listing counter
-
- .psize Y[,X]
- Set the paper size to X wide and Y high. Setting a psize Y of
- zero will suppress form feeds except where demanded by .eject
-
- If the counter goes below zero, listing is suppressed.
-
-
- Listings are a maintained by read calling various listing_<foo>
- functions. What happens most is that the macro NO_LISTING is not
- defined (from the Makefile), then the macro LISTING_NEWLINE expands
- into a call to listing_newline. The call is done from read.c, every
- time it sees a newline, and -l is on the command line.
-
- The function listing_newline remembers the frag associated with the
- newline, and creates a new frag - note that this is wasteful, but not
- a big deal, since listing slows things down a lot anyway. The
- function also rememebers when the filename changes.
-
- When all the input has finished, and gas has had a chance to settle
- down, the listing is output. This is done by running down the list of
- frag/source file records, and opening the files as needed and printing
- out the bytes and chars associated with them.
-
- The only things which the architecture can change about the listing
- are defined in these macros:
-
- LISTING_HEADER The name of the architecture
- LISTING_WORD_SIZE The make of the number of bytes in a word, this determines
- the clumping of the output data. eg a value of
- 2 makes words look like 1234 5678, whilst 1
- would make the same value look like 12 34 56
- 78
- LISTING_LHS_WIDTH Number of words of above size for the lhs
-
- LISTING_LHS_WIDTH_SECOND Number of words for the data on the lhs
- for the second line
-
- LISTING_LHS_CONT_LINES Max number of lines to use up for a continutation
- LISTING_RHS_WIDTH Number of chars from the input file to print
- on a line
- */
+
+ .eject
+ Thow a page
+ .list
+ Increment the enable listing counter
+ .nolist
+ Decrement the enable listing counter
+
+ .psize Y[,X]
+ Set the paper size to X wide and Y high. Setting a psize Y of
+ zero will suppress form feeds except where demanded by .eject
+
+ If the counter goes below zero, listing is suppressed.
+
+
+ Listings are a maintained by read calling various listing_<foo>
+ functions. What happens most is that the macro NO_LISTING is not
+ defined (from the Makefile), then the macro LISTING_NEWLINE expands
+ into a call to listing_newline. The call is done from read.c, every
+ time it sees a newline, and -l is on the command line.
+
+ The function listing_newline remembers the frag associated with the
+ newline, and creates a new frag - note that this is wasteful, but not
+ a big deal, since listing slows things down a lot anyway. The
+ function also rememebers when the filename changes.
+
+ When all the input has finished, and gas has had a chance to settle
+ down, the listing is output. This is done by running down the list of
+ frag/source file records, and opening the files as needed and printing
+ out the bytes and chars associated with them.
+
+ The only things which the architecture can change about the listing
+ are defined in these macros:
+
+ LISTING_HEADER The name of the architecture
+ LISTING_WORD_SIZE The make of the number of bytes in a word, this determines
+ the clumping of the output data. eg a value of
+ 2 makes words look like 1234 5678, whilst 1
+ would make the same value look like 12 34 56
+ 78
+ LISTING_LHS_WIDTH Number of words of above size for the lhs
+
+ LISTING_LHS_WIDTH_SECOND Number of words for the data on the lhs
+ for the second line
+
+ LISTING_LHS_CONT_LINES Max number of lines to use up for a continutation
+ LISTING_RHS_WIDTH Number of chars from the input file to print
+ on a line
+*/
#include "as.h"
#include <obstack.h>
@@ -97,7 +97,6 @@
#include "targ-cpu.h"
#ifndef NO_LISTING
-
#ifndef LISTING_HEADER
#define LISTING_HEADER "GAS LISTING"
#endif
@@ -118,223 +117,250 @@
#endif
+
+
/* This structure remembers which .s were used */
-typedef struct file_info_struct {
- char *filename;
- int linenum;
- FILE *file;
- struct file_info_struct *next;
- int end_pending;
+typedef struct file_info_struct
+{
+ char *filename;
+ int linenum;
+ FILE *file;
+ struct file_info_struct *next;
+ int end_pending;
+
} file_info_type ;
+
+/* this structure rememebrs which line from which file goes into which
+ frag */
+typedef struct list_info_struct
+{
+ /* Frag which this line of source is nearest to */
+ fragS *frag;
+ /* The actual line in the source file */
+ unsigned int line;
+ /* Pointer to the file info struct for the file which this line
+ belongs to */
+ file_info_type *file;
+
+ /* Next in list */
+ struct list_info_struct *next;
-/* this structure rememebrs which line from which file goes into which frag */
-typedef struct list_info_struct {
- /* Frag which this line of source is nearest to */
- fragS *frag;
- /* The actual line in the source file */
- unsigned int line;
- /* Pointer to the file info struct for the file which this line
- belongs to */
- file_info_type *file;
-
- /* Next in list */
- struct list_info_struct *next;
-
-
- /* Pointer to the file info struct for the high level language
- source line that belongs here */
- file_info_type *hll_file;
-
- /* High level language source line */
- int hll_line;
-
-
- /* Pointer to any error message associated with this line */
- char *message;
-
- enum {
- EDICT_NONE,
- EDICT_SBTTL,
- EDICT_TITLE,
- EDICT_NOLIST,
- EDICT_LIST,
- EDICT_EJECT,
- } edict;
- char *edict_arg;
+
+ /* Pointer to the file info struct for the high level language
+ source line that belongs here */
+ file_info_type *hll_file;
+
+ /* High level language source line */
+ int hll_line;
+
+
+ /* Pointer to any error message associated with this line */
+ char *message;
+
+ enum
+ {
+ EDICT_NONE,
+ EDICT_SBTTL,
+ EDICT_TITLE,
+ EDICT_NOLIST,
+ EDICT_LIST,
+ EDICT_EJECT
+ } edict;
+ char *edict_arg;
+
} list_info_type;
+
static struct list_info_struct *head;
struct list_info_struct *listing_tail;
extern int listing;
extern unsigned int physical_input_line;
extern fragS *frag_now;
+
static int paper_width = 200;
static int paper_height = 60;
+
/* this static array is used to keep the text of data to be printed
- before the start of the line. It is stored so we can give a bit
- more info on the next line. To much, and large initialized arrays
- will use up lots of paper. */
+ before the start of the line.
+ It is stored so we can give a bit more info on the next line. To much, and large
+ initialized arrays will use up lots of paper.
+ */
static char data_buffer[100];
static unsigned int data_buffer_size;
+
static void
- listing_message(name, message)
-char *name;
-char *message;
-{
- unsigned int l = strlen(name) + strlen(message) + 1;
- char *n = malloc(l);
- strcpy(n,name);
- strcat(n,message);
- if (listing_tail != (list_info_type *)NULL) {
- listing_tail->message = n;
- }
+DEFUN(listing_message,(name, message),
+ char *name AND
+ char *message)
+{
+ unsigned int l = strlen(name) + strlen(message)+1;
+ char *n = malloc(l);
+ strcpy(n,name);
+ strcat(n,message);
+ if(listing_tail != (list_info_type *)NULL)
+ {
+ listing_tail->message = n;
+ }
+
+}
+
+
- return;
-} /* lising_message() */
void
- listing_warning(message)
-char *message;
+DEFUN(listing_warning,(message),
+ char *message)
{
- listing_message("Warning:", message);
+ listing_message("Warning:", message);
}
-void
- listing_error(message)
-char *message;
+void
+DEFUN(listing_error,(message),
+ char *message)
{
- listing_message("Error:", message);
+ listing_message("Error:", message);
}
+
+
+
static file_info_type *file_info_head;
static file_info_type *
- file_info(file_name)
-char *file_name;
+DEFUN(file_info, (file_name),
+ char *file_name)
{
- /* Find an entry with this file name */
- file_info_type *p = file_info_head;
-
- while (p != (file_info_type *)NULL) {
- if (strcmp(p->filename, file_name) == 0)
- return(p);
- p = p->next;
- }
-
- /* Make new entry */
-
- p = (file_info_type *) xmalloc(sizeof(file_info_type));
- p->next = file_info_head;
- file_info_head = p;
- p->filename = xmalloc(strlen(file_name)+1);
- strcpy(p->filename, file_name);
- p->linenum = 0;
- p->end_pending = 0;
-
- p->file = fopen(p->filename,"r");
- return(p);
-} /* file_info() */
+ /* Find an entry with this file name */
+ file_info_type *p = file_info_head;
+
+ while (p != (file_info_type *)NULL)
+ {
+ if (strcmp(p->filename, file_name) == 0)
+ return p;
+ p = p->next;
+ }
+
+ /* Make new entry */
+
+ p = (file_info_type *)xmalloc(sizeof(file_info_type));
+ p->next = file_info_head;
+ file_info_head = p;
+ p->filename = xmalloc(strlen(file_name)+1);
+ strcpy(p->filename, file_name);
+ p->linenum = 0;
+ p->end_pending = 0;
+
+ p->file = fopen(p->filename,"r");
+ return p;
+
+}
static void
- new_frag()
+DEFUN_VOID(new_frag)
{
- frag_wane(frag_now);
- frag_new(0);
+
+ frag_wane(frag_now);
+ frag_new(0);
+
}
void
- listing_newline(ps)
-char *ps;
+DEFUN(listing_newline,(ps),
+ char *ps)
{
- char *s = ps;
- extern char *file_name;
- static unsigned int last_line = 0xffff ;
-
-
- list_info_type *new;
- if (physical_input_line != last_line) {
- last_line = physical_input_line;
- new_frag();
-
- new = (list_info_type *) malloc(sizeof(list_info_type));
- new->frag = frag_now;
- new->line = physical_input_line ;
- new->file = file_info(file_name);
-
- if (listing_tail) {
- listing_tail->next = new;
- } else {
- head = new;
- }
-
- listing_tail = new;
- new->next = (list_info_type *) NULL;
- new->message = (char *) NULL;
- new->edict = EDICT_NONE;
- new->hll_file = (file_info_type*) NULL;
- new->hll_line = 0;
- new_frag();
- }
+ char *s = ps;
+ extern char *file_name;
+ static unsigned int last_line =0xffff ;
- return;
-} /* listing_newline() */
+
+ list_info_type *new;
+ if (physical_input_line != last_line)
+ {
+ last_line = physical_input_line;
+ new_frag();
+
+ new = (list_info_type *)malloc(sizeof(list_info_type));
+ new->frag = frag_now;
+ new->line = physical_input_line ;
+ new->file = file_info(file_name);
+
+ if (listing_tail)
+ {
+ listing_tail->next = new;
+ }
+ else
+ {
+ head = new;
+ }
+ listing_tail = new;
+ new->next = (list_info_type *)NULL;
+ new->message = (char *)NULL;
+ new->edict = EDICT_NONE;
+ new->hll_file = (file_info_type*)NULL;
+ new->hll_line = 0;
+ new_frag();
+ }
+}
-/* This function returns the next source line from the file supplied,
- truncated to size. It appends a fake line to the end of each input
- file to make. */
+/*
+ This function returns the next source line from the file supplied,
+ truncated to size. It appends a fake line to the end of each input
+ file to make
+*/
static char *
- buffer_line(file, line, size)
-file_info_type *file;
-char *line;
-unsigned int size;
+DEFUN(buffer_line,(file, line, size),
+ file_info_type *file AND
+ char *line AND
+ unsigned int size)
{
- unsigned int count = 0;
- int c;
-
- char *p = line;
-
- /* If we couldn't open the file, return an empty line */
- if (file->file == (FILE*) NULL) {
- return("");
- }
-
- if (file->end_pending == 10) {
- *p ++ = '\n';
- rewind(file->file);
- file->linenum = 0;
- file->end_pending = 0;
- }
-
- c = fgetc(file->file);
- size -= 1; /* leave room for null */
-
- while (c != EOF && c != '\n') {
- if (count < size)
- *p++ = c;
- count++;
-
- c = fgetc(file->file);
- }
-
- if (c == EOF) {
- file->end_pending ++;
- *p++ = 'E';
- *p++ = 'O';
- *p++ = 'F';
- }
-
- file->linenum++;
- *p++ = 0;
- return(line);
-} /* buffer_line() */
+ unsigned int count = 0;
+ int c;
+
+ char *p = line;
+
+ /* If we couldn't open the file, return an empty line */
+ if (file->file == (FILE*)NULL)
+ {
+ return "";
+ }
+
+ if (file->end_pending == 10) {
+ *p ++ = '\n';
+ rewind(file->file);
+ file->linenum = 0;
+ file->end_pending = 0;
+ }
+ c = fgetc(file->file);
+ size -= 1; /* leave room for null */
+
+ while (c != EOF && c != '\n')
+ {
+ if (count < size)
+ *p++ = c;
+ count++;
+
+ c= fgetc(file->file);
+ }
+ if (c == EOF)
+ {
+ file->end_pending ++;
+ *p++ = 'E';
+ *p++ = 'O';
+ *p++ = 'F';
+ }
+ file->linenum++;
+ *p++ = 0;
+ return line;
+}
+
static char *fn;
@@ -344,501 +370,623 @@ static char *title; /* current title */
static char *subtitle; /* current subtitle */
static unsigned int on_page; /* number of lines printed on current page */
-static void
- listing_page(list)
-list_info_type *list;
-{
- /* Grope around, see if we can see a title or subtitle edict
- coming up soon (we look down 10 lines of the page and see
- if it's there). */
-
- if ((eject || (on_page >= paper_height)) && paper_height != 0) {
- unsigned int c = 10;
- int had_title = 0;
- int had_subtitle = 0;
-
- page++;
-
- while (c != 0 && list) {
- if (list->edict == EDICT_SBTTL && !had_subtitle) {
- had_subtitle = 1;
- subtitle = list->edict_arg;
- }
-
- if (list->edict == EDICT_TITLE && !had_title) {
- had_title = 1;
- title = list->edict_arg;
- }
- list = list->next;
- --c;
- }
-
- if (page > 1) {
- printf("\f");
- }
-
- printf("%s %s \t\t\tpage %d\n", LISTING_HEADER, fn, page);
- printf("%s\n", title);
- printf("%s\n", subtitle);
- on_page = 3;
- eject = 0;
- }
- return;
-} /* listing_page() */
+static void
+DEFUN(listing_page,(list),
+ list_info_type *list)
+{
+ /* Grope around, see if we can see a title or subtitle edict coming up
+ soon (we look down 10 lines of the page and see if it's there)*/
+ if ((eject || (on_page >= paper_height)) && paper_height != 0)
+ {
+ unsigned int c = 10;
+ int had_title = 0;
+ int had_subtitle = 0;
+
+ page++;
+
+ while (c != 0 && list)
+ {
+ if (list->edict == EDICT_SBTTL && !had_subtitle)
+ {
+ had_subtitle = 1;
+ subtitle = list->edict_arg;
+ }
+ if (list->edict == EDICT_TITLE && !had_title)
+ {
+ had_title = 1;
+ title = list->edict_arg;
+ }
+ list = list->next;
+ c--;
+ }
+
+
+ if (page > 1)
+ {
+ printf("\f");
+ }
+
+ printf("%s %s \t\t\tpage %d\n", LISTING_HEADER, fn, page);
+ printf("%s\n", title);
+ printf("%s\n", subtitle);
+ on_page = 3;
+ eject = 0;
+ }
+}
static unsigned int
- calc_hex(list)
-list_info_type *list;
+DEFUN(calc_hex,(list),
+ list_info_type *list)
{
- list_info_type *first = list;
- list_info_type *last = first;
- unsigned int address = ~0;
-
- fragS *frag;
- fragS *frag_ptr;
-
- unsigned int byte_in_frag = 0;
-
- int anything = 0;
-
- /* Find first frag which says it belongs to this line */
- frag = list->frag;
- while (frag && frag->line != list)
- frag = frag->fr_next;
-
- frag_ptr = frag;
-
- data_buffer_size = 0;
-
- /* Dump all the frags which belong to this line */
- while (frag_ptr != (fragS *)NULL && frag_ptr->line == first) {
- /* Print as many bytes from the fixed part as is sensible */
- while(byte_in_frag < frag_ptr->fr_fix && data_buffer_size < sizeof(data_buffer)-10) {
- if (address == ~0) {
- address = frag_ptr->fr_address;
- }
-
- sprintf(data_buffer + data_buffer_size, "%02X", (frag_ptr->fr_literal[byte_in_frag]) & 0xff);
- data_buffer_size += 2;
- byte_in_frag++;
- }
-
- /* Print as many bytes from the variable part as is sensible */
- while (byte_in_frag < frag_ptr->fr_var * frag_ptr->fr_offset
- && data_buffer_size < sizeof(data_buffer)-10) {
- if (address == ~0) {
- address = frag_ptr->fr_address;
- }
- data_buffer[data_buffer_size++] = '*';
- data_buffer[data_buffer_size++] = '*';
-
- byte_in_frag++;
- }
-
- frag_ptr = frag_ptr->fr_next;
- }
-
- data_buffer[data_buffer_size++] = 0;
- return address;
-} /* calc_hex() */
+ list_info_type *first = list;
+ list_info_type *last = first;
+ unsigned int address = ~0;
+
+ fragS *frag;
+ fragS *frag_ptr;
+
+ unsigned int byte_in_frag = 0;
+
+ int anything = 0;
+
+ /* Find first frag which says it belongs to this line */
+ frag = list->frag;
+ while (frag && frag->line != list)
+ frag = frag->fr_next;
+
+ frag_ptr = frag;
+
+ data_buffer_size = 0;
+
+ /* Dump all the frags which belong to this line */
+ while (frag_ptr != (fragS *)NULL && frag_ptr->line == first)
+ {
+ /* Print as many bytes from the fixed part as is sensible */
+ while(byte_in_frag < frag_ptr->fr_fix && data_buffer_size < sizeof(data_buffer)-10)
+ {
+ if (address == ~0)
+ {
+ address = frag_ptr->fr_address;
+ }
+
+ sprintf(data_buffer + data_buffer_size,
+ "%02X",
+ (frag_ptr->fr_literal[byte_in_frag]) & 0xff);
+ data_buffer_size += 2;
+ byte_in_frag++;
+ }
+ {
+ unsigned int var_rep_max = byte_in_frag;
+ unsigned int var_rep_idx = byte_in_frag;
+
+ /* Print as many bytes from the variable part as is sensible */
+ while (byte_in_frag < frag_ptr->fr_var * frag_ptr->fr_offset
+ && data_buffer_size < sizeof(data_buffer)-10)
+ {
+ if (address == ~0)
+ {
+ address = frag_ptr->fr_address;
+ }
+sprintf(data_buffer + data_buffer_size,
+ "%02X",
+ (frag_ptr->fr_literal[var_rep_idx]) & 0xff);
+#if 0
+ data_buffer[data_buffer_size++] = '*';
+ data_buffer[data_buffer_size++] = '*';
+#endif
+ data_buffer_size +=2;
+
+ var_rep_idx ++;
+ byte_in_frag++;
+
+ if (var_rep_idx >= frag_ptr->fr_var)
+ var_rep_idx = var_rep_max;
+ }
+ }
+
+ frag_ptr = frag_ptr->fr_next;
+ }
+ data_buffer[data_buffer_size++] = 0;
+ return address;
+}
+
+
+
+
+
static void
- print_lines(list, string, address)
-list_info_type *list;
-char *string;
-unsigned int address;
-{
- unsigned int idx;
- unsigned int nchars;
- unsigned int lines;
- unsigned int byte_in_word =0;
- char *src = data_buffer;
+DEFUN(print_lines,(list, string, address),
+list_info_type *list AND
+char *string AND
+unsigned int address)
+{
+ unsigned int idx;
+ unsigned int nchars;
+ unsigned int lines;
+ unsigned int byte_in_word =0;
+ char *src = data_buffer;
+
+ /* Print the stuff on the first line */
+ listing_page(list);
+ nchars = (LISTING_WORD_SIZE*2 +1) * LISTING_LHS_WIDTH ;
+ /* Print the hex for the first line */
+ if (address == ~0)
+ {
+ printf("% 4d ", list->line);
+ for (idx = 0; idx < nchars; idx++)
+ printf(" ");
+
+ printf("\t%s\n", string ? string : "");
+ on_page++;
+ listing_page(0);
+
+ }
+ else
+ {
+ if (had_errors())
+ {
+ printf("% 4d ???? ", list->line);
+ }
+ else
+ {
+ printf("% 4d %04x ", list->line, address);
+ }
+
+ /* And the data to go along with it */
+ idx = 0;
+
+ while (*src && idx < nchars)
+ {
+ printf("%c%c", src[0], src[1]);
+ src += 2;
+ byte_in_word++;
+ if (byte_in_word == LISTING_WORD_SIZE)
+ {
+ printf(" ");
+ idx++;
+ byte_in_word = 0;
+ }
+ idx+=2;
+ }
+
+ for (;idx < nchars; idx++)
+ printf(" ");
+
+ printf("\t%s\n", string ? string : "");
+ on_page++;
+ listing_page(list);
+ if (list->message)
+ {
+ printf("**** %s\n",list->message);
+ listing_page(list);
+ on_page++;
+ }
+
+ for (lines = 0;
+ lines < LISTING_LHS_CONT_LINES
+ && *src;
+ lines++) {
+ nchars = ((LISTING_WORD_SIZE*2) +1) * LISTING_LHS_WIDTH_SECOND -1;
+ idx = 0;
+ /* Print any more lines of data, but more compactly */
+ printf("% 4d ", list->line);
+
+ while (*src && idx < nchars)
+ {
+ printf("%c%c", src[0], src[1]);
+ src+=2;
+ idx+=2;
+ byte_in_word++;
+ if (byte_in_word == LISTING_WORD_SIZE)
+ {
+ printf(" ");
+ idx++;
+ byte_in_word = 0;
+ }
+ }
- /* Print the stuff on the first line */
+ printf("\n");
+ on_page++;
listing_page(list);
- nchars = (LISTING_WORD_SIZE * 2 + 1) * LISTING_LHS_WIDTH ;
- /* Print the hex for the first line */
- if (address == ~0) {
- printf("% 4d ", list->line);
- for (idx = 0; idx < nchars; idx++)
- printf(" ");
-
- printf("\t%s\n", string ? string : "");
- on_page++;
- listing_page(0);
- } else {
- if (had_errors()) {
- printf("% 4d ???? ", list->line);
- } else {
- printf("% 4d %04x ", list->line, address);
- }
-
- /* And the data to go along with it */
- idx = 0;
-
- while (*src && idx < nchars) {
- printf("%c%c", src[0], src[1]);
- src += 2;
- byte_in_word++;
-
- if (byte_in_word == LISTING_WORD_SIZE) {
- printf(" ");
- idx++;
- byte_in_word = 0;
- }
- idx+=2;
- }
-
- for (;idx < nchars; idx++)
- printf(" ");
-
- printf("\t%s\n", string ? string : "");
- on_page++;
- listing_page(list);
- if (list->message) {
- printf("**** %s\n",list->message);
- listing_page(list);
- on_page++;
- }
-
- for (lines = 0; lines < LISTING_LHS_CONT_LINES && *src; lines++) {
- nchars = ((LISTING_WORD_SIZE*2) +1) * LISTING_LHS_WIDTH_SECOND -1;
- idx = 0;
- /* Print any more lines of data, but more compactly */
- printf("% 4d ", list->line);
-
- while (*src && idx < nchars) {
- printf("%c%c", src[0], src[1]);
- src+=2;
- idx+=2;
- byte_in_word++;
- if (byte_in_word == LISTING_WORD_SIZE) {
- printf(" ");
- idx++;
- byte_in_word = 0;
- }
- }
-
- printf("\n");
- on_page++;
- listing_page(list);
- }
- }
-} /* print_lines() */
+ }
+
+
+ }
+}
+
+
+
+
static void
- list_symbol_table()
+DEFUN_VOID(list_symbol_table)
{
- extern symbolS *symbol_rootP;
- symbolS *ptr;
-
- eject = 1;
- listing_page(0);
- printf("DEFINED SYMBOLS\n");
- on_page++;
-
- for (ptr = symbol_rootP; ptr != (symbolS*)NULL; ptr = symbol_next(ptr)) {
- if (ptr->sy_frag->line) {
- if (strlen(S_GET_NAME(ptr))) {
- printf("%20s:%-5d %2d:%08x %s \n",
- ptr->sy_frag->line->file->filename,
- ptr->sy_frag->line->line,
- S_GET_SEGMENT(ptr),
- S_GET_VALUE(ptr),
- S_GET_NAME(ptr));
-
- on_page++;
- listing_page(0);
- }
- }
-
- }
-
- printf("\n");
+ extern symbolS *symbol_rootP;
+
+ symbolS *ptr ;
+ eject = 1;
+ listing_page(0);
+ printf("DEFINED SYMBOLS\n");
+ on_page++;
+
+ for (ptr = symbol_rootP; ptr != (symbolS*)NULL; ptr = symbol_next(ptr))
+ {
+ if (ptr->sy_frag->line)
+ {
+ if (strlen(S_GET_NAME(ptr)))
+ {
+ printf("%20s:%-5d %2d:%08x %s \n",
+ ptr->sy_frag->line->file->filename,
+ ptr->sy_frag->line->line,
+ S_GET_SEGMENT(ptr),
+ S_GET_VALUE(ptr),
+ S_GET_NAME(ptr));
+
on_page++;
listing_page(0);
- printf("UNDEFINED SYMBOLS\n");
+ }
+ }
+
+ }
+ printf("\n");
+ on_page++;
+ listing_page(0);
+ printf("UNDEFINED SYMBOLS\n");
+ on_page++;
+ listing_page(0);
+
+ for (ptr = symbol_rootP; ptr != (symbolS*)NULL; ptr = symbol_next(ptr))
+ {
+ if (ptr && strlen(S_GET_NAME(ptr)) != 0)
+ {
+ if (ptr->sy_frag->line == 0)
+ {
+ printf("%s\n", S_GET_NAME(ptr));
on_page++;
listing_page(0);
-
- for (ptr = symbol_rootP; ptr != (symbolS*)NULL; ptr = symbol_next(ptr)) {
- if (ptr && strlen(S_GET_NAME(ptr)) != 0) {
- if (ptr->sy_frag->line == 0) {
- printf("%s\n", S_GET_NAME(ptr));
- on_page++;
- listing_page(0);
- }
- }
- }
-
- return;
-} /* list_symbol_table() */
+ }
+ }
+ }
+}
void
- print_source(current_file, list, buffer, width)
-file_info_type *current_file;
-list_info_type *list;
-char *buffer;
-unsigned int width;
-{
- if (current_file->file) {
- while (current_file->linenum < list->hll_line) {
- char * p = buffer_line(current_file, buffer, width);
- printf("%4d:%-13s **** %s\n", current_file->linenum, current_file->filename, p);
- on_page++;
- listing_page(list);
- }
- }
-
- return;
-} /* print_source() */
+DEFUN(print_source,(current_file, list, buffer, width),
+ file_info_type *current_file AND
+ list_info_type *list AND
+ char *buffer AND
+ unsigned int width)
+{
+ if (current_file->file) {
+ while (current_file->linenum < list->hll_line)
+ {
+ char * p = buffer_line(current_file, buffer, width);
+ printf("%4d:%-13s **** %s\n", current_file->linenum, current_file->filename, p);
+ on_page++;
+ listing_page(list);
+ }
+ }
+}
/* Sometimes the user doesn't want to be bothered by the debugging
records inserted by the compiler, see if the line is suspicioous */
static int
- debugging_pseudo(line)
-char *line;
+DEFUN(debugging_pseudo,(line),
+ char *line)
{
- while (isspace(*line))
- line++;
-
- if (*line != '.') return 0;
-
- line++;
-
- if (strncmp(line, "def",3) == 0) return 1;
- if (strncmp(line, "val",3) == 0) return 1;
- if (strncmp(line, "scl",3) == 0) return 1;
- if (strncmp(line, "line",4) == 0) return 1;
- if (strncmp(line, "endef",5) == 0) return 1;
- if (strncmp(line, "ln",2) ==0) return 1;
- if (strncmp(line, "type",4) ==0) return 1;
- if (strncmp(line, "size",4) == 0) return 1;
- if (strncmp(line, "dim",3) ==0) return 1;
- if (strncmp(line, "tag",3) == 0) return 1;
-
- return(0);
-} /* debugging_pseudo() */
+ while (isspace(*line))
+ line++;
+
+ if(*line != '.') return 0;
+
+ line++;
+
+ if (strncmp(line, "def",3) == 0) return 1;
+ if (strncmp(line, "val",3) == 0) return 1;
+ if (strncmp(line, "scl",3) == 0) return 1;
+ if (strncmp(line, "line",4) == 0) return 1;
+ if (strncmp(line, "endef",5) == 0) return 1;
+ if (strncmp(line, "ln",2) ==0) return 1;
+ if (strncmp(line, "type",4) ==0) return 1;
+ if (strncmp(line, "size",4) == 0) return 1;
+ if (strncmp(line, "dim",3) ==0) return 1;
+ if (strncmp(line, "tag",3) == 0) return 1;
+
+ return 0;
+
+}
void
- listing_listing(name)
-char *name;
-{
- char *buffer;
- char *message;
- char *p;
- file_info_type *current_hll_file = (file_info_type *) NULL;
- int on_page = 0;
- int show_listing = 1;
- list_info_type *list = head;
- unsigned int addr = 0;
- unsigned int page = 1;
- unsigned int prev = 0;
- unsigned int width;
-
- buffer = malloc(LISTING_RHS_WIDTH);
+DEFUN(listing_listing,(name),
+ char *name)
+{
+ list_info_type *list = head;
+ file_info_type *current_hll_file = (file_info_type *)NULL;
+
+ unsigned int page= 1;
+ unsigned int prev = 0;
+ char *message;
+ char *buffer;
+ char *p;
+ unsigned int addr = 0;
+ int on_page = 0;
+ int show_listing = 1;
+ unsigned int width;
+
+ buffer = malloc(LISTING_RHS_WIDTH);
+ eject = 1;
+ list = head;
+
+ while (list != (list_info_type *)NULL && 0)
+ {
+ if (list->next)
+ list->frag = list->next->frag;
+ list = list->next;
+
+ }
+
+ list = head->next;
+
+
+ while ( list)
+ {
+ width = LISTING_RHS_WIDTH > paper_width ? paper_width :
+ LISTING_RHS_WIDTH;
+
+ switch (list->edict) {
+ case EDICT_LIST:
+ show_listing++;
+ break;
+ case EDICT_NOLIST:
+ show_listing--;
+ break;
+ case EDICT_EJECT:
+ break;
+ case EDICT_NONE:
+ break;
+ case EDICT_TITLE:
+ title = list->edict_arg;
+ break;
+ case EDICT_SBTTL:
+ subtitle = list->edict_arg;
+ break;
+ default:
+ abort();
+ }
+
+ if (show_listing > 0)
+ {
+ /* Scan down the list and print all the stuff which can be done
+ with this line (or lines) */
+ message = 0;
+
+ if (list->hll_file)
+ {
+ current_hll_file = list->hll_file;
+ }
+
+ if (current_hll_file && list->hll_line && listing & LISTING_HLL)
+ {
+ print_source(current_hll_file, list, buffer, width);
+ }
+
+ p = buffer_line(list->file, buffer, width);
+
+ if (! ((listing & LISTING_NODEBUG) && debugging_pseudo(p)))
+ {
+ print_lines(list, p, calc_hex(list));
+ }
+
+ if (list->edict == EDICT_EJECT)
+ {
eject = 1;
- list = head;
-
- while (list != (list_info_type *)NULL && 0) {
- if (list->next)
- list->frag = list->next->frag;
- list = list->next;
- }
-
- list = head->next;
-
- while (list) {
- width = LISTING_RHS_WIDTH > paper_width ? paper_width : LISTING_RHS_WIDTH;
-
- switch (list->edict) {
- case EDICT_LIST:
- show_listing++;
- break;
- case EDICT_NOLIST:
- show_listing--;
- break;
- case EDICT_EJECT:
- break;
- case EDICT_NONE:
- break;
- case EDICT_TITLE:
- title = list->edict_arg;
- break;
- case EDICT_SBTTL:
- subtitle = list->edict_arg;
- break;
- default:
- abort();
- }
-
- if (show_listing > 0) {
- /* Scan down the list and print all the stuff which can be done
- with this line (or lines) */
- message = 0;
-
- if (list->hll_file) {
- current_hll_file = list->hll_file;
- }
-
- if (current_hll_file && list->hll_line && listing & LISTING_HLL) {
- print_source(current_hll_file, list, buffer, width);
- }
-
- p = buffer_line(list->file, buffer, width);
-
- if (! ((listing & LISTING_NODEBUG) && debugging_pseudo(p))) {
- print_lines(list, p, calc_hex(list));
- }
-
- if (list->edict == EDICT_EJECT) {
- eject = 1;
- }
- } else {
-
- p = buffer_line(list->file, buffer, width);
- }
-
- list = list->next;
- }
- free(buffer);
-} /* listing_listing() */
+ }
+ }
+ else
+ {
+
+ p = buffer_line(list->file, buffer, width);
+ }
+
+ list = list->next;
+ }
+ free(buffer);
+}
void
- listing_print(name)
-char *name;
+DEFUN(listing_print,(name),
+ char *name)
{
- title = "";
- subtitle = "";
-
- if (listing & LISTING_NOFORM)
- {
- paper_height = 0;
- }
-
- if (listing & LISTING_LISTING)
- {
- listing_listing(name);
-
- }
- if (listing & LISTING_SYMBOLS)
- {
- list_symbol_table();
- }
-} /* listing_print() */
+ title = "";
+ subtitle = "";
+
+ if (listing & LISTING_NOFORM)
+ {
+ paper_height = 0;
+ }
+
+ if (listing & LISTING_LISTING)
+ {
+ listing_listing(name);
+
+ }
+ if (listing & LISTING_SYMBOLS)
+ {
+ list_symbol_table();
+ }
+}
void
- listing_file(name)
-char *name;
+DEFUN(listing_file,(name),
+char *name)
{
- fn = name;
+ fn = name;
}
void
- listing_eject()
+DEFUN_VOID(listing_eject)
{
- listing_tail->edict = EDICT_EJECT;
- return;
+ listing_tail->edict = EDICT_EJECT;
}
void
- listing_flags()
+DEFUN_VOID(listing_flags)
{
-
+
+}
+void
+DEFUN(listing_list,(on),
+ unsigned int on)
+{
+ listing_tail->edict = on ? EDICT_LIST : EDICT_NOLIST;
}
+
void
- listing_list(on)
-unsigned int on;
+DEFUN_VOID(listing_psize)
{
- listing_tail->edict = on ? EDICT_LIST : EDICT_NOLIST;
+ paper_height = get_absolute_expression();
+
+ if (paper_height < 0 || paper_height > 1000)
+ {
+ paper_height = 0;
+ as_warn("strantge paper height, set to no form");
+ }
+ if (*input_line_pointer == ',')
+ {
+ input_line_pointer++;
+ paper_width = get_absolute_expression();
+ }
}
void
- listing_psize()
+DEFUN(listing_title,(depth),
+ unsigned int depth)
{
- paper_height = get_absolute_expression();
-
- if (paper_height < 0 || paper_height > 1000) {
- paper_height = 0;
- as_warn("strantge paper height, set to no form");
+ char *start;
+ char *title;
+ unsigned int length;
+
+ SKIP_WHITESPACE();
+ if (*input_line_pointer=='\"') {
+ input_line_pointer++;
+ start = input_line_pointer;
+
+ while (*input_line_pointer)
+ {
+ if (*input_line_pointer == '\"')
+ {
+ length = input_line_pointer - start;
+ title = malloc(length + 1);
+ memcpy(title, start, length);
+ title[length] = 0;
+ listing_tail->edict = depth ? EDICT_SBTTL : EDICT_TITLE;
+ listing_tail->edict_arg = title;
+ input_line_pointer++;
+ demand_empty_rest_of_line();
+ return;
}
-
- if (*input_line_pointer == ',') {
- input_line_pointer++;
- paper_width = get_absolute_expression();
+ else if (*input_line_pointer == '\n')
+ {
+ as_bad("New line in title");
+ demand_empty_rest_of_line();
+ return;
}
-
- return;
-} /* listing_psize() */
+ else
+ {
+ input_line_pointer++;
+ }
+ }
+ }
+ else
+ {
+ as_bad("expecting title in quotes");
+ }
+}
+
void
- listing_title(depth)
-unsigned int depth;
+DEFUN(listing_source_line,(line),
+ unsigned int line)
{
- char *start;
- char *title;
- unsigned int length;
-
- SKIP_WHITESPACE();
-
- if (*input_line_pointer=='\"') {
- input_line_pointer++;
- start = input_line_pointer;
-
- while (*input_line_pointer) {
- if (*input_line_pointer == '\"') {
- length = input_line_pointer - start;
- title = malloc(length + 1);
- memcpy(title, start, length);
- title[length] = 0;
- listing_tail->edict = depth ? EDICT_SBTTL : EDICT_TITLE;
- listing_tail->edict_arg = title;
- input_line_pointer++;
- demand_empty_rest_of_line();
- return;
- } else if (*input_line_pointer == '\n') {
- as_bad("New line in title");
- demand_empty_rest_of_line();
- return;
- } else {
- input_line_pointer++;
- }
- }
- } else {
- as_bad("expecting title in quotes");
- }
-
- return;
-} /* listing_title() */
+ new_frag();
+ listing_tail->hll_line = line;
+ new_frag();
+
+}
+void
+DEFUN(listing_source_file,(file),
+ char *file)
+{
+ listing_tail->hll_file = file_info(file);
+}
-void
- listing_source_line(line)
-unsigned int line;
+
+#else
+
+
+/* Dummy functions for when compiled without listing enabled */
+
+void
+DEFUN_VOID(listing_flags)
+{
+ s_ignore();
+}
+
+void DEFUN_VOID(listing_list)
{
- new_frag();
- listing_tail->hll_line = line;
- new_frag();
- return;
-} /* lising_source_line() */
+ s_ignore();
+}
+
+void DEFUN_VOID(listing_eject)
+{
+ s_ignore();
+}
+void DEFUN(listing_psize)
+{
+ s_ignore();
+}
+void DEFUN(listing_title, (depth),
+unsigned int depth)
+{
+ s_ignore();
+}
void
- listing_source_file(file)
-char *file;
+DEFUN(listing_file,(name),
+char *name)
{
- listing_tail->hll_file = file_info(file);
+
+}
+
+void DEFUN(listing_newline,(name),
+char *name)
+{
+
}
-#endif /* not NO_LISTING */
+void DEFUN(listing_source_line,(n),
+unsigned int n)
+{
+
+}
+void DEFUN(listing_source_file, (n),
+char *n)
+{
+
+}
+
+
+
+#endif
-/* end of listing.c */
diff --git a/gas/write.c b/gas/write.c
index 89b6682..71004474 100644
--- a/gas/write.c
+++ b/gas/write.c
@@ -18,16 +18,7 @@
along with GAS; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
-/*
-
- This thing should be set up to do byteordering correctly. But...
-
- In order to cross-assemble the target machine must have an a.out header
- similar to the one in a.out.h on THIS machine. Byteorder doesn't matter,
- we take special care of it, but the numbers must be the same SIZE (# of
- bytes) and in the same PLACE. If this is not true, you will have some
- trouble.
- */
+/* This thing should be set up to do byteordering correctly. But... */
#include "as.h"
#include "subsegs.h"
@@ -45,11 +36,9 @@
#ifndef MANY_SEGMENTS
static struct frag *text_frag_root;
static struct frag *data_frag_root;
-static struct frag *bss_frag_root;
static struct frag *text_last_frag; /* Last frag in segment. */
static struct frag *data_last_frag; /* Last frag in segment. */
-static struct frag *bss_last_frag; /* Last frag in segment. */
#endif
static object_headers headers;
@@ -94,7 +83,9 @@ symbolS *add_symbol; /* X_add_symbol. */
symbolS *sub_symbol; /* X_subtract_symbol. */
long offset; /* X_add_number. */
int pcrel; /* TRUE if PC-relative relocation. */
-enum reloc_type r_type; /* Relocation type */
+#if defined(TC_SPARC) || defined(TC_A29K)
+int r_type; /* Relocation type */
+#endif
{
fixS *fixP;
@@ -107,8 +98,9 @@ enum reloc_type r_type; /* Relocation type */
fixP->fx_subsy = sub_symbol;
fixP->fx_offset = offset;
fixP->fx_pcrel = pcrel;
+#if defined(TC_SPARC) || defined(TC_A29K)
fixP->fx_r_type = r_type;
-
+#endif
/* JF these 'cuz of the NS32K stuff */
fixP->fx_im_disp = 0;
fixP->fx_pcrel_adjust = 0;
@@ -207,23 +199,17 @@ void write_object_file()
for (frchainP = frchain_root; frchainP; frchainP = next_frchainP) {
know( frchainP->frch_root );
* prev_fragPP = frchainP->frch_root;
- prev_fragPP = & frchainP->frch_last->fr_next;
- next_frchainP = frchainP->frch_next;
-
- if (next_frchainP == NULL)
- {
- bss_last_frag = frchainP->frch_last;
- }
- else if (next_frchainP == data0_frchainP)
- {
- text_last_frag = frchainP->frch_last;
- prev_fragPP = & data_frag_root;
- }
- else if (next_frchainP == bss0_frchainP)
- {
- data_last_frag = frchainP->frch_last;
- prev_fragPP = & bss_frag_root;
- }
+ prev_fragPP = & frchainP->frch_last->fr_next;
+
+ if (((next_frchainP = frchainP->frch_next) == NULL)
+ || next_frchainP == data0_frchainP) {
+ prev_fragPP = & data_frag_root;
+ if (next_frchainP) {
+ text_last_frag = frchainP->frch_last;
+ } else {
+ data_last_frag = frchainP->frch_last;
+ }
+ }
} /* walk the frag chain */
/*
@@ -248,7 +234,6 @@ void write_object_file()
relax_segment(text_frag_root, SEG_TEXT);
relax_segment(data_frag_root, SEG_DATA);
- relax_segment(bss_frag_root, SEG_BSS);
/*
* Now the addresses of frags are correct within the segment.
*/
@@ -287,18 +272,7 @@ void write_object_file()
bss_address_frag.fr_address = (H_GET_TEXT_SIZE(&headers) +
H_GET_DATA_SIZE(&headers));
- H_SET_BSS_SIZE(&headers, bss_last_frag->fr_address);
-
- /*
- * now fixup all bss frags addresses
- */
- if (bss_frag_root)
- {
- relax_addressT slide;
- slide = bss_address_frag.fr_address;
- for (fragP = bss_frag_root; fragP; fragP = fragP->fr_next)
- fragP->fr_address += slide;
- }
+ H_SET_BSS_SIZE(&headers,local_bss_counter);
/*
*
@@ -410,11 +384,17 @@ void write_object_file()
lie->sub,
lie->addnum,
0, 0, 2, 0, 0);
-#else /* TC_NS32K */
+#elif defined(TC_SPARC) || defined(TC_A29K)
fix_new( lie->frag, lie->word_goes_here - lie->frag->fr_literal,
2, lie->add,
lie->sub, lie->addnum,
0, NO_RELOC);
+#else
+ fix_new( lie->frag, lie->word_goes_here - lie->frag->fr_literal,
+ 2, lie->add,
+ lie->sub, lie->addnum,
+ 0, 0);
+
#endif /* TC_NS32K */
/* md_number_to_chars(lie->word_goes_here,
S_GET_VALUE(lie->add)
@@ -620,14 +600,14 @@ void write_object_file()
void relax_segment(segment_frag_root, segment)
struct frag * segment_frag_root;
-segT segment; /* SEG_DATA or SEG_TEXT or SEG_BSS */
+segT segment; /* SEG_DATA or SEG_TEXT */
{
register struct frag * fragP;
register relax_addressT address;
/* register relax_addressT old_address; JF unused */
/* register relax_addressT new_address; JF unused */
#ifndef MANY_SEGMENTS
- know(segment == SEG_DATA || segment == SEG_TEXT || segment == SEG_BSS);
+ know(segment == SEG_DATA || segment == SEG_TEXT);
#endif
/* In case md_estimate_size_before_relax() wants to make fixSs. */
subseg_change(segment, 0);
@@ -768,10 +748,7 @@ segT segment; /* SEG_DATA or SEG_TEXT or SEG_BSS */
if (symbolP) {
#ifdef MANY_SEGMENTS
#else
- know((S_GET_SEGMENT(symbolP) == SEG_ABSOLUTE)
- || (S_GET_SEGMENT(symbolP) == SEG_DATA)
- || (S_GET_SEGMENT(symbolP) == SEG_TEXT)
- || (S_GET_SEGMENT(symbolP) == SEG_BSS));
+ know((S_GET_SEGMENT(symbolP) == SEG_ABSOLUTE) || (S_GET_SEGMENT(symbolP) == SEG_DATA) || (S_GET_SEGMENT(symbolP) == SEG_TEXT));
know(symbolP->sy_frag);
know(!(S_GET_SEGMENT(symbolP) == SEG_ABSOLUTE) || (symbolP->sy_frag == &zero_address_frag));
#endif
@@ -1084,16 +1061,10 @@ segT this_segment_type; /* N_TYPE bits for segment. */
#endif /* TC_I960 */
#ifdef OBJ_COFF
- /* This really needed to be
- like this for COFF output.
- - mtranle@paris
-
- But I'm not sure it's right
- for i960 or a29k coff.
- xoxorich. */
-
+#ifdef TE_I386AIX
if (S_IS_COMMON(add_symbolP))
add_number += S_GET_VALUE(add_symbolP);
+#endif /* TE_I386AIX */
#endif /* OBJ_COFF */
++seg_reloc_count;
diff --git a/gas/write.h b/gas/write.h
index 1dc899e..9ce6529 100644
--- a/gas/write.h
+++ b/gas/write.h
@@ -35,49 +35,32 @@
#define S_LOCAL_NAME(s) (LOCAL_LABEL(S_GET_NAME(s)))
-/* The bit_fix was implemented to support machines that need variables
- to be inserted in bitfields other than 1, 2 and 4 bytes.
- Furthermore it gives us a possibillity to mask in bits in the symbol
- when it's fixed in the objectcode and check the symbols limits.
-
- The or-mask is used to set the huffman bits in displacements for the
- ns32k port.
- The acbi, addqi, movqi, cmpqi instruction requires an assembler that
- can handle bitfields. Ie handle an expression, evaluate it and insert
- the result in an some bitfield. ( ex: 5 bits in a short field of a opcode)
- */
-
-struct bit_fix {
- int fx_bit_size; /* Length of bitfield */
- int fx_bit_offset; /* Bit offset to bitfield */
- long fx_bit_base; /* Where do we apply the bitfix.
- If this is zero, default is assumed. */
- long fx_bit_base_adj;/* Adjustment of base */
- long fx_bit_max; /* Signextended max for bitfield */
- long fx_bit_min; /* Signextended min for bitfield */
- long fx_bit_add; /* Or mask, used for huffman prefix */
-};
-typedef struct bit_fix bit_fixS;
+#include "bit_fix.h"
+
/*
* FixSs may be built up in any order.
*/
struct fix {
- fragS *fx_frag; /* Which frag? */
- long fx_where; /* Where is the 1st byte to fix up? */
- symbolS *fx_addsy; /* NULL or Symbol whose value we add in. */
- symbolS *fx_subsy; /* NULL or Symbol whose value we subtract. */
- long fx_offset; /* Absolute number we add in. */
- struct fix *fx_next; /* NULL or -> next fixS. */
- short int fx_size; /* How many bytes are involved? */
- char fx_pcrel; /* TRUE: pc-relative. */
- char fx_pcrel_adjust;/* pc-relative offset adjust */
- char fx_im_disp; /* TRUE: value is a displacement */
- bit_fixS *fx_bit_fixP; /* IF NULL no bitfix's to do */
- char fx_bsr; /* sequent-hack */
- enum reloc_type fx_r_type; /* Sparc hacks */
- char fx_callj; /* TRUE if target is a 'callj'
- (used by i960) */
+ fragS *fx_frag; /* Which frag? */
+ long fx_where; /* Where is the 1st byte to fix up? */
+ symbolS *fx_addsy; /* NULL or Symbol whose value we add in. */
+ symbolS *fx_subsy; /* NULL or Symbol whose value we subtract. */
+ long fx_offset; /* Absolute number we add in. */
+ struct fix *fx_next; /* NULL or -> next fixS. */
+ short int fx_size; /* How many bytes are involved? */
+ char fx_pcrel; /* TRUE: pc-relative. */
+ char fx_pcrel_adjust; /* pc-relative offset adjust */
+ char fx_im_disp; /* TRUE: value is a displacement */
+ bit_fixS *fx_bit_fixP; /* IF NULL no bitfix's to do */
+ char fx_bsr; /* sequent-hack */
+#if defined(TC_SPARC) || defined(TC_A29K)
+ /* Hacks for machines where the type of reloc can't be
+ worked out by looking at how big it is */
+
+ int fx_r_type;
+#endif
+ char fx_callj; /* TRUE if target is a 'callj' (used by i960) */
long fx_addnumber;
};
@@ -88,6 +71,7 @@ COMMON char *next_object_file_charP;
#ifndef MANY_SEGMENTS
COMMON fixS *text_fix_root, *text_fix_tail; /* Chains fixSs. */
COMMON fixS *data_fix_root, *data_fix_tail; /* Chains fixSs. */
+COMMON fixS *bss_fix_root, *bss_fix_tail; /* Chains fixSs. */
#endif
COMMON fixS **seg_fix_rootP, **seg_fix_tailP; /* -> one of above. */
extern long string_byte_count;
@@ -95,7 +79,7 @@ extern int section_alignment[];
#if __STDC__ == 1
-bit_fixS *bit_fix_new(char size, char offset, long base_type, long base_adj, long min, long max, long add);
+bit_fixS *bit_fix_new(int size, int offset, long base_type, long base_adj, long min, long max, long add);
void append(char **charPP, char *fromP, unsigned long length);
void record_alignment(segT seg, int align);
void write_object_file(void);