read.c (s_align_bytes): Properly record alignment.
authorKen Raeburn <raeburn@cygnus>
Thu, 27 May 1993 19:42:23 +0000 (19:42 +0000)
committerKen Raeburn <raeburn@cygnus>
Thu, 27 May 1993 19:42:23 +0000 (19:42 +0000)
expr.c (__): Undefine before defining.
as.c (got_sig): Don't return anything; return type might be void.
Whitespace/comment cleanup in frags.c.
Some patches for `-pedantic' or `-fno-common' compilation.
(Some of these changes are from Michael Meissner; see change log.)

gas/ChangeLog
gas/config/obj-elf.c [new file with mode: 0644]
gas/config/tc-a29k.c
gas/config/tc-h8500.c
gas/config/tc-i386.c
gas/config/tc-m68k.c
gas/expr.c
gas/read.c

index 7c039b9e46c3d53cfcec1ad0157c20b164f05d67..0329af13dcf15dd6b613d0a37d9c9d68d6133f06 100644 (file)
@@ -1,3 +1,38 @@
+Thu May 27 13:02:15 1993  Ken Raeburn  (raeburn@cambridge.cygnus.com)
+
+       * frags.c (zero_address_frag, bss_address_frag): These are
+       external.
+
+       * tc.h (md_reloc_size): This is const.
+       * config/tc-{a29k,h8300,h8500,i386,i860,i960,m68k,ns32k,z8k}.c
+       (md_reloc_size): Now const.
+
+       * config/aout_gnu.h (enum machine_type, enum reloc_type): Delete
+       trailing commas.
+       * as.h (enum _segT): Ditto.
+
+       * struc-symbol.h (N_TYPE_seg): This should be const.
+
+Thu May 27 11:43:59 1993  Michael Meissner  (meissner@osf.org)
+
+       * config/obj-ecoff.c (add_file): Cast file_name to char * in
+       listing_source_file call.
+
+       * config/obj-elf.c (elf_stab_symbol_string): Cast first argument
+       of subseg_new call to eliminate const attribute.
+       (obj_elf_stab): Ditto.
+       (obj_symbol_new_hook): Cast first argument of bzero call to char *.
+
+       * read.c (s_align_bytes): Properly record alignment.
+
+       * expr.c (__): Undefine __ macro before use, since OSF/1 uses it
+       for the prototype/no prototype macro.
+
+       * as.c (got_sig): Don't do return ((SIGTY) 0), SIGTY might well be
+       void.
+
+       * as.h (relax_stateT enum): Delete trailing comma.
+
 Thu May 27 11:07:50 1993  Ian Lance Taylor  (ian@cygnus.com)
 
        * app.c (do_scrub_begin): Let line_comment_chars override
diff --git a/gas/config/obj-elf.c b/gas/config/obj-elf.c
new file mode 100644 (file)
index 0000000..e122d37
--- /dev/null
@@ -0,0 +1,1189 @@
+/* ELF object file format
+   Copyright (C) 1992, 1993 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. */
+
+/* HP PA-RISC support was contributed by the Center for Software Science
+   at the University of Utah.  */
+
+#include "as.h"
+#include "aout/stab_gnu.h"
+#include "obstack.h"
+
+static void obj_elf_stab PARAMS ((int what));
+static void obj_elf_line PARAMS ((void));
+static void obj_elf_desc PARAMS ((void));
+static void obj_elf_version PARAMS ((void));
+static void obj_elf_section PARAMS ((int));
+static void obj_elf_size PARAMS ((void));
+static void obj_elf_type PARAMS ((void));
+static void obj_elf_ident PARAMS ((void));
+
+const pseudo_typeS obj_pseudo_table[] = {
+  { "ident",   obj_elf_ident,          0 },
+  { "section", obj_elf_section,        0 },
+  { "size",    obj_elf_size,           0 },
+  { "type",    obj_elf_type,           0 },
+  { "version",  obj_elf_version,       0 },
+
+  /* These are used for stabs-in-elf configurations.  */
+  { "desc",    obj_elf_desc,           0       },
+  { "line",    obj_elf_line,           0       },
+  { "stabd",   obj_elf_stab,           'd'     },
+  { "stabn",   obj_elf_stab,           'n'     },
+  { "stabs",   obj_elf_stab,           's'     },
+  /* This is used on Solaris 2.x on SPARC, but not supported yet.  */
+  { "xstabs",  s_ignore,               0       },
+
+  { NULL}      /* end sentinel */
+};
+
+static void
+obj_elf_section (xxx)
+     int xxx;
+{
+  char *string;
+  asection *sec;
+
+  /* Initialize this with inclusive-or of all flags that can be cleared
+     by attributes, but not set by them.  Also include flags that won't
+     get set properly in the assembler, but which the user/compiler
+     shouldn't be expected to set.  */
+  flagword flags = SEC_READONLY | SEC_ALLOC | SEC_RELOC;
+  /* Initialize this with the default flags to be used if none are
+     specified.  */
+  flagword default_flags = SEC_ALLOC | SEC_RELOC;
+
+  string = demand_copy_C_string (&xxx);
+  SKIP_WHITESPACE ();
+  if (*input_line_pointer != ',')
+    flags = default_flags;
+  while (*input_line_pointer == ',')
+    {
+      flagword bit;
+      int len, inv;
+      char *p, oldp;
+
+      input_line_pointer++;
+      if (*input_line_pointer != '#')
+       {
+         as_bad ("unrecognized syntax in .section command");
+         ignore_rest_of_line ();
+         break;
+       }
+      input_line_pointer++;
+
+#define CHECK(X,BIT,NEG)       \
+      if (!strncmp(X,input_line_pointer,len = sizeof(X) - 1)) { \
+       bit = BIT; inv = NEG; goto match; }
+
+      CHECK ("write", SEC_READONLY, 1);
+      CHECK ("alloc", SEC_ALLOC, 0);
+#undef CHECK
+
+      p = input_line_pointer;
+      while (!is_end_of_line[*p] && *p != 0 && *p != ',')
+       p++;
+      *p = 0;
+      oldp = *p;
+      as_bad ("unrecognized section attribute `%s' ignored",
+             input_line_pointer);
+      *p = oldp;
+      continue;
+
+    match:
+      if (inv)
+       flags &= ~bit;
+      else
+       flags |= bit;
+      input_line_pointer += len;
+    }
+  demand_empty_rest_of_line ();
+
+  sec = bfd_get_section_by_name (stdoutput, string);
+  if (sec == 0)
+    {
+      sec = bfd_make_section_old_way (stdoutput, string);
+      bfd_set_section_flags (stdoutput, sec,
+                            /* @@ What should the flags be??  */
+                            flags);
+      sec->output_section = sec;
+    }
+  subseg_change (sec, 0);
+}
+
+#if 0
+/* pa-spaces.c -- Space/subspace support for the HP PA-RISC version of GAS */
+
+/* for space, subspace, and symbol maintenance on HP 9000 Series 800 */
+
+space_dict_chainS *space_dict_root;
+space_dict_chainS *space_dict_last;
+
+space_dict_chainS *current_space;
+subspace_dict_chainS *current_subspace;
+#endif
+
+symbolS *start_symbol_root;
+symbolS *start_symbol_last;
+
+#if 0 /* I really don't think this belongs in this file.  */
+void pa_spaces_begin()
+{
+  space_dict_chainS *space;
+  int i;
+  subsegT now_subseg   = now_subseg;
+
+  space_dict_root = NULL;
+  space_dict_last = NULL;
+
+  start_symbol_root = NULL;
+  start_symbol_last = NULL;
+
+  /* create default space and subspace dictionaries */
+
+  i = 0;
+  while ( pa_def_spaces[i].name ) {
+         if ( pa_def_spaces[i].alias )
+             pa_def_spaces[i].segment = subseg_new(pa_def_spaces[i].alias,0);
+         else
+             pa_def_spaces[i].segment = bfd_make_section_old_way(stdoutput,pa_def_spaces[i].name);
+
+         create_new_space(pa_def_spaces[i].name,pa_def_spaces[i].spnum,
+                          pa_def_spaces[i].loadable,pa_def_spaces[i].defined,
+                          pa_def_spaces[i].private,pa_def_spaces[i].sort,0,
+                          pa_def_spaces[i].segment);
+         i++;
+  }
+
+  i = 0;
+  while ( pa_def_subspaces[i].name ) {
+         space = pa_segment_to_space(pa_def_spaces[pa_def_subspaces[i].def_space_index].segment);
+         if ( space ) {
+                 create_new_subspace(space,
+                                     pa_def_subspaces[i].name,pa_def_subspaces[i].defined,
+                                     pa_def_subspaces[i].loadable,
+                                     pa_def_subspaces[i].code_only,pa_def_subspaces[i].common,
+                                     pa_def_subspaces[i].dup_common,pa_def_subspaces[i].zero,
+                                     pa_def_subspaces[i].sort,pa_def_subspaces[i].access,
+                                     pa_def_subspaces[i].space_index,
+                                     pa_def_subspaces[i].alignment,
+                                     pa_def_subspaces[i].quadrant,
+                                     pa_def_spaces[pa_def_subspaces[i].def_space_index].segment);
+                 subseg_new(pa_def_subspaces[i].name,pa_def_subspaces[i].subsegment);
+         }
+         else
+             as_fatal("Internal error: space missing for subspace \"%s\"\n",
+                      pa_def_subspaces[i].name);
+         i++;
+  }
+}
+
+space_dict_chainS *create_new_space(name,spnum,loadable,defined,private,sort,defined_in_file,seg)
+     char *name;
+     int spnum;
+     char loadable;
+     char defined;
+     char private;
+     char sort;
+     char defined_in_file;
+     asection * seg;
+
+{
+  Elf_Internal_Shdr *new_space;
+  space_dict_chainS *chain_entry;
+
+  new_space = (Elf_Internal_Shdr *)xmalloc(sizeof(Elf_Internal_Shdr));
+  if ( !new_space )
+    as_fatal("Out of memory: could not allocate new Elf_Internal_Shdr: %s\n",name);
+
+  /*
+  new_space->space_number = spnum;
+  new_space->is_loadable = loadable & 1;
+  new_space->is_defined = defined & 1;
+  new_space->is_private = private & 1;
+  new_space->sort_key = sort & 0xff;
+
+  new_space->loader_fix_index = ~0;
+  new_space->loader_fix_quantity = 0;
+  new_space->init_pointer_index = ~0;
+  new_space->init_pointer_quantity = 0;
+  new_space->subspace_quantity = 0;
+  */
+
+  chain_entry = (space_dict_chainS *)xmalloc(sizeof(space_dict_chainS));
+  if ( !chain_entry )
+    as_fatal("Out of memory: could not allocate new space chain entry: %s\n",name);
+
+  SPACE_NAME(chain_entry) = (char *)xmalloc(strlen(name)+1);
+  strcpy(SPACE_NAME(chain_entry),name);
+
+  chain_entry->sd_entry = new_space;
+  chain_entry->sd_defined = defined_in_file;
+  chain_entry->sd_seg = seg;
+  chain_entry->sd_last_subseg = -1;
+  chain_entry->sd_next = NULL;
+
+  SPACE_SPNUM(chain_entry) = spnum;
+  SPACE_LOADABLE(chain_entry) = loadable & 1;
+  SPACE_DEFINED(chain_entry) = defined & 1;
+  SPACE_PRIVATE(chain_entry) = private & 1;
+  SPACE_SORT(chain_entry) = sort & 0xff;
+
+  /* find spot for the new space based on its sort key */
+
+  if ( !space_dict_last )
+    space_dict_last = chain_entry;
+
+  if ( space_dict_root == NULL )        /* if root is null, it is very easy */
+    space_dict_root = chain_entry;
+  else
+    {
+      space_dict_chainS *sdcP;
+      space_dict_chainS *last_sdcP;
+
+      sdcP = space_dict_root;
+      last_sdcP = NULL;
+
+      while ( sdcP ) {
+       if ( SPACE_SORT(sdcP) < SPACE_SORT(chain_entry) ) {
+         last_sdcP = sdcP;
+         sdcP = sdcP->sd_next;
+       }
+       else if ( SPACE_SORT(sdcP) == SPACE_SORT(chain_entry) ) {
+         last_sdcP = sdcP;
+         sdcP = sdcP->sd_next;
+       }
+       else if ( SPACE_SORT(sdcP) > SPACE_SORT(chain_entry) ) {
+         break;
+       }       
+      }
+
+      if ( last_sdcP ) {
+       chain_entry->sd_next = sdcP;
+       last_sdcP->sd_next = chain_entry;
+      }
+      else {
+       space_dict_root = chain_entry;
+       chain_entry->sd_next = sdcP;
+      }
+
+      if ( chain_entry->sd_next  == NULL )
+       space_dict_last = chain_entry;
+    }
+
+  return chain_entry;
+}
+
+subspace_dict_chainS
+*create_new_subspace(space,name,defined,loadable,code_only,common,dup_common,
+                    is_zero,sort,access,space_index,alignment,quadrant,seg)
+     space_dict_chainS *space;
+     char *name;
+     char defined,loadable,code_only,common,dup_common,is_zero;
+     char sort;
+     int access;
+     int space_index;
+     int alignment;
+     int quadrant;
+     asection * seg;
+{
+  Elf_Internal_Shdr * new_subspace;
+  subspace_dict_chainS * chain_entry;
+  symbolS * start_symbol;
+
+  new_subspace = (Elf_Internal_Shdr *)xmalloc(sizeof(Elf_Internal_Shdr));
+  if ( !new_subspace )
+    as_fatal("Out of memory: could not allocate new Elf_Internal_Shdr: %s\n",
+           name);
+
+  /*
+  new_subspace->space_index = space_index;
+  new_subspace->fixup_request_index = ~0;
+  */
+
+  chain_entry = (subspace_dict_chainS *)xmalloc(sizeof(subspace_dict_chainS));
+  if ( !chain_entry )
+    as_fatal("Out of memory: could not allocate new subspace chain entry: %s\n",name);
+
+  chain_entry->ssd_entry = new_subspace;
+  SUBSPACE_NAME(chain_entry) = (char *)xmalloc(strlen(name)+1);
+  strcpy(SUBSPACE_NAME(chain_entry),name);
+
+  SUBSPACE_ACCESS(chain_entry) = access & 0x7f;
+  SUBSPACE_LOADABLE(chain_entry) = loadable & 1;
+  SUBSPACE_COMMON(chain_entry) = common & 1;
+  SUBSPACE_DUP_COMM(chain_entry) = dup_common & 1;
+  SUBSPACE_SORT(chain_entry) = sort & 0xff;
+  SET_SUBSPACE_CODE_ONLY(chain_entry,code_only & 1);
+  SUBSPACE_ALIGN(chain_entry) = alignment & 0xffff;
+  SUBSPACE_QUADRANT(chain_entry) = quadrant & 0x3;
+  SUBSPACE_SUBSPACE_START(chain_entry) = pa_subspace_start(space,quadrant);
+
+  chain_entry->ssd_defined = defined;
+  chain_entry->ssd_space_number = space_index;
+  chain_entry->ssd_subseg = pa_next_subseg(space);
+  chain_entry->ssd_seg = seg;
+  SUBSPACE_ZERO(chain_entry) = is_zero;
+  chain_entry->ssd_last_align = 1;
+  chain_entry->ssd_next = NULL;
+
+  /* find spot for the new subspace based on its sort key */
+
+  if ( space->sd_subspaces == NULL )        /* if root is null, it is very easy */
+    space->sd_subspaces = chain_entry;
+  else
+    {
+      subspace_dict_chainS *ssdcP;
+      subspace_dict_chainS *last_ssdcP;
+
+      ssdcP = space->sd_subspaces;
+      last_ssdcP = NULL;
+
+      while ( ssdcP ) {
+       if ( SUBSPACE_SORT(ssdcP) < SUBSPACE_SORT(chain_entry) ) {
+         last_ssdcP = ssdcP;
+         ssdcP = ssdcP->ssd_next;
+       }
+       else if ( SUBSPACE_SORT(ssdcP) == SUBSPACE_SORT(chain_entry) ) {
+         last_ssdcP = ssdcP;
+         ssdcP = ssdcP->ssd_next;
+       }
+       else if ( SUBSPACE_SORT(ssdcP) > SUBSPACE_SORT(chain_entry) ) {
+         break;
+       }       
+      }
+
+      if ( last_ssdcP ) {
+       chain_entry->ssd_next = ssdcP;
+       last_ssdcP->ssd_next = chain_entry;
+      }
+      else {
+       space->sd_subspaces = chain_entry;
+       chain_entry->ssd_next = ssdcP;
+      }
+    }
+
+  start_symbol = pa_set_start_symbol(seg,space->sd_last_subseg);
+  chain_entry->ssd_start_sym = start_symbol;
+  return chain_entry;
+
+}
+
+subspace_dict_chainS
+*update_subspace(name,defined,loadable,code_only,common,dup_common,sort,zero,
+                access,space_index,alignment,quadrant,subseg)
+     char *name;
+     char defined,loadable,code_only,common,dup_common,zero;
+     char sort;
+     int access;
+     int space_index;
+     int alignment;
+     int quadrant;
+     subsegT subseg;
+{
+  subspace_dict_chainS *chain_entry;
+  subspace_dict_chainS *is_defined_subspace();
+
+  if ( (chain_entry = is_defined_subspace(name,subseg)) ) {
+
+    SUBSPACE_ACCESS(chain_entry) = access & 0x7f;
+    SUBSPACE_LOADABLE(chain_entry) = loadable & 1;
+    SUBSPACE_COMMON(chain_entry) = common & 1;
+    SUBSPACE_DUP_COMM(chain_entry) = dup_common & 1;
+    SET_SUBSPACE_CODE_ONLY(chain_entry,code_only & 1);
+    SUBSPACE_SORT(chain_entry) = sort & 0xff;
+    /* chain_entry->ssd_entry->space_index = space_index; */
+    SUBSPACE_ALIGN(chain_entry) = alignment & 0xffff;
+    SUBSPACE_QUADRANT(chain_entry) = quadrant & 0x3;
+
+    chain_entry->ssd_defined = defined;
+    chain_entry->ssd_space_number = space_index;
+    SUBSPACE_ZERO(chain_entry) = zero;
+  }
+  else
+    chain_entry = NULL;
+
+  return chain_entry;
+
+}
+
+space_dict_chainS *is_defined_space(name)
+     char *name;
+{
+  space_dict_chainS *spaceCh;
+
+  for (spaceCh = space_dict_root;spaceCh;spaceCh=spaceCh->sd_next ) {
+    if ( strcmp(SPACE_NAME(spaceCh),name) == 0 ) {
+      return spaceCh;
+    }
+  }
+
+  return NULL;
+}
+
+space_dict_chainS *pa_segment_to_space(seg)
+     asection * seg;
+{
+  space_dict_chainS *spaceCh;
+
+  for (spaceCh = space_dict_root;spaceCh;spaceCh=spaceCh->sd_next ) {
+    if ( spaceCh->sd_seg == seg ) {
+      return spaceCh;
+    }
+  }
+
+  return NULL;
+}
+
+subspace_dict_chainS *is_defined_subspace(name,subseg)
+     char *name;
+     subsegT subseg;
+{
+  space_dict_chainS *spaceCh;
+  subspace_dict_chainS *subspCh;
+
+  for ( spaceCh = space_dict_root; spaceCh; spaceCh = spaceCh->sd_next ) {
+    for ( subspCh = spaceCh->sd_subspaces; subspCh; subspCh=subspCh->ssd_next ) {
+      /*
+       if ( strcmp(SUBSPACE_NAME(subspCh),name) == 0 &&
+           subspCh->ssd_subseg == subseg ) {
+       */
+       if ( strcmp(SUBSPACE_NAME(subspCh),name) == 0 ) {
+         return subspCh;
+       }
+    }
+  }
+  return NULL;
+}
+
+subspace_dict_chainS *pa_subsegment_to_subspace(seg,subseg)
+    asection * seg;
+    subsegT subseg;
+{
+  space_dict_chainS *spaceCh;
+  subspace_dict_chainS *subspCh;
+
+  for ( spaceCh = space_dict_root; spaceCh; spaceCh = spaceCh->sd_next ) {
+    if ( spaceCh->sd_seg == seg ) {
+      for (subspCh = spaceCh->sd_subspaces;subspCh;subspCh=subspCh->ssd_next ) {
+       if ( subspCh->ssd_subseg == (int)subseg ) {
+         return subspCh;
+       }
+      }
+    }
+  }
+
+  return NULL;
+}
+
+space_dict_chainS *pa_find_space_by_number(number)
+     int number;
+{
+  space_dict_chainS *spaceCh;
+
+  for (spaceCh = space_dict_root;spaceCh;spaceCh=spaceCh->sd_next ) {
+    if ( SPACE_SPNUM(spaceCh) == number ) {
+      return spaceCh;
+    }
+  }
+
+  return NULL;
+}
+
+unsigned int pa_subspace_start(space,quadrant)
+     space_dict_chainS *space;
+     int quadrant;
+{
+  if ( (strcasecmp(SPACE_NAME(space),"$PRIVATE$") == 0) &&
+       quadrant == 1 ) {
+    return 0x40000000;
+  }
+  else if ( space->sd_seg == data_section && quadrant == 1 ) {  /* in case name is */
+                                                            /* already converted */
+                                                            /* to a space dict- */
+                                                            /* ionary index */
+    return 0x40000000;
+  }
+  else
+    return 0;
+}
+
+int pa_next_subseg(space)
+     space_dict_chainS *space;
+{
+
+  space->sd_last_subseg++;
+  return space->sd_last_subseg;
+}
+
+int is_last_defined_subspace(ssd)
+     subspace_dict_chainS *ssd;
+{
+
+  for ( ;ssd; ssd = ssd->ssd_next ) {
+    if ( ssd->ssd_defined )
+      return FALSE;
+  }
+
+  return TRUE;
+}
+
+symbolS *pa_get_start_symbol(seg,subseg)
+     asection * seg;
+     subsegT subseg;
+{
+  symbolS *start_symbol;
+  subspace_dict_chainS *ssd;
+
+  start_symbol = NULL;
+
+  /* each time a new space is created, build a symbol called LS$START_seg_subseg$ */
+  /* where <space-name> is the name of the space */
+  /* the start symbol will be SS_LOCAL and ST_CODE */
+
+  if ( seg == bfd_make_section_old_way ( stdoutput, ".text" ) ||
+       seg == bfd_make_section_old_way ( stdoutput, ".data" ) ||
+       seg == bfd_make_section_old_way ( stdoutput, GDB_DEBUG_SPACE_NAME ) ) {
+         ssd = pa_subsegment_to_subspace(seg,subseg);
+         if ( ssd ) {
+                 start_symbol = ssd->ssd_start_sym;
+         }
+         else
+             as_fatal("Internal error: missing subspace for (seg,subseg)=('%s',%d)",
+                      seg->name,subseg);
+  }
+  else
+      as_fatal("Internal error: attempt to find start symbol for unloadable segment: '%s'",
+              seg->name);
+
+  return start_symbol;
+}
+
+/*
+  Function to define a symbol whose address is the beginning of a subspace.
+  This function assumes the symbol is to be defined for the current subspace.
+ */
+
+symbolS *pa_set_start_symbol(seg,subseg)
+     asection * seg;
+     subsegT subseg;
+{
+  symbolS *start_symbol;
+  subspace_dict_chainS *ssd;
+  char *symbol_name;
+
+  symbol_name = (char *)xmalloc(strlen("LS$START__000000$")+strlen(seg->name)+1);
+
+  sprintf(symbol_name,"LS$START_%s_%03d$",seg->name,subseg);
+
+  start_symbol
+      = symbol_new(symbol_name,seg,0,frag_now); /* XXX: not sure if value s.b. 0 or frag s.b. NULL */
+
+  start_symbol->bsym->flags    = BSF_LOCAL;    /* XXX: isn't there a macro defined for this? */
+
+  /* each time a new space is created, build a symbol called LS$START_seg_subseg$ */
+  /* where <space-name> is the name of the space */
+  /* the start symbol will be SS_LOCAL and ST_CODE */
+  /* This function assumes that (seg,subseg) is a new subsegment(subspace) */
+
+  if ( seg == bfd_make_section_old_way ( stdoutput, ".text" ) ||
+       seg == bfd_make_section_old_way ( stdoutput, ".data" ) ||
+       seg == bfd_make_section_old_way ( stdoutput, GDB_DEBUG_SPACE_NAME ) ) {
+         ssd = pa_subsegment_to_subspace(seg,subseg);
+         if ( ssd ) {
+                 ssd->ssd_start_sym = start_symbol;
+         }
+         else
+             as_fatal("Internal error: missing subspace for (seg,subseg)=('%s',%d)",
+                      seg,subseg);
+  }
+  else
+      as_fatal("Internal error: attempt to define start symbol for unloadable segment: '%s'",
+              seg->name);
+
+  return start_symbol;
+}
+#endif
+
+int
+obj_elf_frob_symbol (sym, punt)
+     symbolS *sym;
+     int *punt;
+{
+
+       /* If this is a local symbol, are there any relocations for */
+       /* which need this symbol?      */
+
+       /* To find this out, we examine all relocations in all bfd */
+       /* sections that have relocations.  If there is one that */
+       /* references this symbol, we need to keep this symbol.  In */
+       /* this case, we return a true status.  In all other cases, we */
+       /* return a false status.       */
+
+       if ( S_IS_LOCAL(sym) ) {
+               asymbol *bsym = sym->bsym;      
+               bfd *abfd = bsym->the_bfd;
+               asection *bsec;
+
+               for ( bsec = abfd->sections; bsec; bsec = bsec->next ) {
+                       struct reloc_cache_entry **rlocs = bsec->orelocation;
+                       int rcnt = bsec->reloc_count;
+
+                       if ( rlocs ) {
+                               int i;
+
+                               for ( i = 0; i < rcnt; i++ ) {
+                                       if ( rlocs[i]->sym_ptr_ptr
+                                           && rlocs[i]->sym_ptr_ptr[0] == bsym )
+                                               return 1;
+                               }
+                       }
+               }
+       }
+       return 0;
+}
+
+static void obj_elf_line() {
+       /* Assume delimiter is part of expression.
+          BSD4.2 as fails with delightful bug, so we
+          are not being incompatible here. */
+       new_logical_line((char *)NULL, (int)(get_absolute_expression()));
+       demand_empty_rest_of_line();
+} /* obj_elf_line() */
+
+/*
+ *                     stab()
+ *
+ * Handle .stabX directives, which used to be open-coded.
+ * So much creeping featurism overloaded the semantics that we decided
+ * to put all .stabX thinking in one place. Here.
+ *
+ * We try to make any .stabX directive legal. Other people's AS will often
+ * do assembly-time consistency checks: eg assigning meaning to n_type bits
+ * and "protecting" you from setting them to certain values. (They also zero
+ * certain bits before emitting symbols. Tut tut.)
+ *
+ * If an expression is not absolute we either gripe or use the relocation
+ * information. Other people's assemblers silently forget information they
+ * don't need and invent information they need that you didn't supply.
+ *
+ * .stabX directives always make a symbol table entry. It may be junk if
+ * the rest of your .stabX directive is malformed.
+ */
+
+/*
+ *                      pa_stab_symbol_string()
+ *
+ * Build a string dictionary entry for a .stabX symbol.
+ * The symbol is added to the .stabstr section.
+ *
+ */
+
+static unsigned int gdb_string_index = 0;
+
+static unsigned int
+elf_stab_symbol_string(string)
+     char *string;
+{
+  asection *save_seg;
+  asection *seg;
+  subsegT save_subseg;
+  unsigned int length;
+  unsigned int old_gdb_string_index;
+  char *clengthP;
+  int i;
+  char c;
+
+  old_gdb_string_index = 0;
+  length = strlen(string);
+  clengthP = (char *)&length;
+  if ( length > 0 ) {                  /* Ordinary case. */
+    save_seg = now_seg;
+    save_subseg = now_subseg;
+
+    /* Create the stab sections, if they are not already created. */
+    seg = bfd_get_section_by_name(stdoutput,".stabstr");
+    if ( seg == 0 ) {
+           seg = bfd_make_section_old_way(stdoutput,".stabstr");
+           bfd_set_section_flags (stdoutput,
+                                  seg,
+                                  SEC_READONLY | SEC_ALLOC | SEC_LOAD );
+    }
+    subseg_new((char *) seg->name,save_subseg);
+    old_gdb_string_index = gdb_string_index;
+    i = 0;
+    while ( (c = *string++) )
+      {
+       i++;
+        gdb_string_index++;
+       FRAG_APPEND_1_CHAR( c );
+      }
+    {
+      FRAG_APPEND_1_CHAR( (char)0 );
+      i++;
+      gdb_string_index++;
+    }
+    while ( i%4 != 0 ) {
+      FRAG_APPEND_1_CHAR( (char)0 );
+      i++;
+      gdb_string_index++;
+    }
+    subseg_new((char *) save_seg->name,save_subseg);
+  }
+
+  return old_gdb_string_index;
+}
+
+unsigned int
+elf_stab_symbol(symbolP,stab_type)
+     symbolS *symbolP;
+     int stab_type;
+{
+  unsigned int length;
+  int i;
+  char c;
+  char *toP;
+
+  /* the string index portion of the stab */
+
+  toP = frag_more( sizeof(long) +
+                  sizeof(S_GET_TYPE(symbolP)) +
+                  sizeof(S_GET_OTHER(symbolP)) +
+                  sizeof(S_GET_DESC(symbolP)));
+  md_number_to_chars(toP,symbolP->sy_name_offset,sizeof(long));
+  md_number_to_chars(toP,
+                    S_GET_TYPE(symbolP),
+                    sizeof(S_GET_TYPE(symbolP)));
+  md_number_to_chars(toP + sizeof(S_GET_TYPE(symbolP)),
+                    S_GET_OTHER(symbolP),
+                    sizeof(S_GET_OTHER(symbolP)));
+  md_number_to_chars(toP + sizeof(S_GET_TYPE(symbolP))
+                        + sizeof(S_GET_OTHER(symbolP)),
+                    S_GET_DESC(symbolP),
+                    sizeof(S_GET_DESC(symbolP)));
+
+  /* n_value has to be relocated */
+
+  /* Don't bother relocating if we're only adding in a constant. */
+
+  if ((stab_type == 's' || stab_type == 'n') && symbolP->sy_forward == 0)
+         S_SET_VALUE(symbolP,S_GET_VALUE(symbolP->sy_forward));
+
+  toP = frag_more(4);
+  md_number_to_chars(toP, S_GET_VALUE(symbolP),
+                    sizeof(S_GET_VALUE(symbolP)));
+
+#if 0
+  if ( (stab_type == 's' || stab_type == 'n') && symbolP->sy_forward )
+    {
+      i = S_GET_TYPE(symbolP) & N_TYPE;
+      fix_new_hppa(frag_now,   /* which frag */
+                  toP-frag_now->fr_literal, /* where */
+                  4,           /* size */
+                  symbolP->sy_forward, /* addr of symbol for this stab */
+                  (asymbol *)NULL,
+                  0,
+                  i == N_UNDF || i == N_ABS,   /* 1 if internal relocation */
+                  R_HPPA,      /* reloc type */
+                  e_fsel,      /* fixup field = F% */
+                  32,
+                  0,           /* arg_reloc descriptor */
+                  (char *)0
+                  );
+    }
+  else if ( stab_type == 'd' )
+    {
+      fix_new_hppa (frag_now,  /* which frag */
+                   toP-frag_now->fr_literal, /* where */
+                   4,          /* size */
+                   symbolP,    /* addr of symbol for this stab */
+                   (asymbol *)NULL,
+                   0,
+                   0,
+                   R_HPPA,     /* reloc type */
+                   e_fsel,     /* fixup field = F% */
+                   32,
+                   0,          /* arg_reloc descriptor */
+                   (char *)0
+                   );
+    }
+#else
+  /* What needs to replace the above code?  */
+  abort ();
+#endif
+}
+
+static void obj_elf_stab(what)
+     int what;
+{
+  extern int listing;
+
+  symbolS *    symbolP = 0;
+  char *       string;
+  int saved_type = 0;
+  int length;
+  int goof = 0;
+  long longint;
+  asection *saved_seg = now_seg;
+  asection *seg;
+  subsegT subseg = now_subseg;
+
+  seg = bfd_get_section_by_name(stdoutput,".stab");
+  if ( seg == 0 )
+    {
+      seg = bfd_make_section_old_way(stdoutput,".stab");
+      bfd_set_section_flags (stdoutput,
+                            seg,
+                            SEC_READONLY | SEC_ALLOC | SEC_LOAD | SEC_RELOC);
+    }
+
+  /*
+   * Enter with input_line_pointer pointing past .stabX and any following
+   * whitespace.
+   */
+  if (what == 's') {
+      string = demand_copy_C_string(& length);
+      SKIP_WHITESPACE();
+      if (* input_line_pointer == ',')
+       input_line_pointer ++;
+      else
+       {
+         as_bad("I need a comma after symbol's name");
+         goof = 1;
+       }
+    }
+  else
+    string = "";
+
+  /*
+   * Input_line_pointer->after ','.  String->symbol name.
+   */
+  if (! goof)
+    {
+      symbolP = symbol_new(string, &bfd_und_section, 0, (struct frag *)0);
+
+      /* enter the string in the .stab string table (section .stabstr) */
+      symbolP->sy_name_offset = elf_stab_symbol_string(string);
+
+      switch (what)
+       {
+       case 'd':
+         S_SET_NAME(symbolP, NULL); /* .stabd feature. */
+         S_SET_VALUE(symbolP, obstack_next_free(&frags) - frag_now->fr_literal);
+         S_SET_SEGMENT(symbolP, now_seg);
+         symbolP->sy_frag = frag_now;
+         break;
+
+       case 'n':
+         symbolP->sy_frag = &zero_address_frag;
+         break;
+
+       case 's':
+         symbolP->sy_frag = & zero_address_frag;
+         break;
+
+       default:
+         BAD_CASE(what);
+         break;
+       }
+
+      if (get_absolute_expression_and_terminator(&longint) == ',')
+       {
+         saved_type = longint;
+         S_SET_TYPE (symbolP, saved_type);
+       }
+      else
+       {
+         as_bad("I want a comma after the n_type expression");
+         goof = 1;
+         input_line_pointer --; /* Backup over a non-',' char. */
+       }
+    }
+
+  if (!goof)
+    {
+      if (get_absolute_expression_and_terminator(&longint) == ',')
+       S_SET_OTHER(symbolP, longint);
+      else
+       {
+         as_bad("I want a comma after the n_other expression");
+         goof = 1;
+         input_line_pointer--; /* Backup over a non-',' char. */
+       }
+    }
+
+  if (!goof)
+    {
+      S_SET_DESC(symbolP, get_absolute_expression());
+      if (what == 's' || what == 'n')
+       {
+         if (*input_line_pointer != ',')
+           {
+             as_bad("I want a comma after the n_desc expression");
+             goof = 1;
+           }
+         else
+           {
+             input_line_pointer++;
+           }
+       }
+    }
+
+  if ( !goof ) {
+         if ( what=='s' || what=='n' ) {
+                 pseudo_set(symbolP);
+                 S_SET_TYPE (symbolP, saved_type);
+         }
+         /* Emit the stab symbol. */
+         subseg_new((char *) seg->name,subseg);
+         elf_stab_symbol(symbolP, what);
+         subseg_new((char *) saved_seg->name,subseg);
+
+         if ( what=='s' || what=='n' && symbolP->sy_forward == NULL ) {
+                 /* symbol is not needed in the regular symbol table */
+                 symbol_remove(symbolP,&symbol_rootP,&symbol_lastP);
+         }
+
+  }
+
+#ifndef NO_LISTING
+  if (listing && !goof)
+    switch (S_GET_TYPE (symbolP))
+      {
+      case N_SLINE:
+       listing_source_line (S_GET_DESC (symbolP));
+       break;
+      case N_SO:
+      case N_SOL:
+       listing_source_file (string);
+       break;
+      }
+#endif
+
+  if (goof)
+    ignore_rest_of_line();
+  else
+    demand_empty_rest_of_line ();
+} /* obj_elf_stab() */
+
+static void obj_elf_desc() {
+       char *name;
+       char c;
+       char *p;
+       symbolS *symbolP;
+       int temp;
+       
+       /*
+        * Frob invented at RMS' request. Set the n_desc of a symbol.
+        */
+       name = input_line_pointer;
+       c = get_symbol_end();
+       p = input_line_pointer;
+       * p = c;
+       SKIP_WHITESPACE();
+       if (*input_line_pointer != ',') {
+               *p = 0;
+               as_bad("Expected comma after name \"%s\"", name);
+               *p = c;
+               ignore_rest_of_line();
+       } else {
+               input_line_pointer ++;
+               temp = get_absolute_expression();
+               *p = 0;
+               symbolP = symbol_find_or_make(name);
+               *p = c;
+               S_SET_DESC(symbolP,temp);
+       }
+       demand_empty_rest_of_line();
+} /* obj_elf_desc() */
+
+void obj_read_begin_hook()
+{
+}
+
+void obj_symbol_new_hook(symbolP)
+symbolS *symbolP;
+{
+  elf_symbol_type *esym = (elf_symbol_type *)symbolP;
+
+  /* There is an Elf_Internal_Sym and an Elf_External_Sym.  For now,
+     just zero them out.  */
+
+  bzero((char *) &esym->internal_elf_sym,sizeof(Elf_Internal_Sym));
+  bzero((char *) &esym->native_elf_sym,sizeof(Elf_External_Sym));
+}
+
+static void obj_elf_version()
+{
+    char *name;
+    unsigned int c;
+    char ch;
+    char *p;
+    int temp;
+    symbolS *  symbolP;
+    asection *seg = now_seg;
+    subsegT subseg = now_subseg;
+    Elf_Internal_Note i_note;
+    Elf_External_Note e_note;
+    asection *note_secp = (asection *)NULL;
+    int i, len;
+
+    SKIP_WHITESPACE();
+    if (* input_line_pointer == '\"') {
+      ++input_line_pointer; /* -> 1st char of string. */
+      name = input_line_pointer;
+
+      while ( is_a_char(c = next_char_of_string()) )
+             ;
+      c = *input_line_pointer;
+      *input_line_pointer = '\0';
+      *(input_line_pointer-1) = '\0';
+      *input_line_pointer = c;
+
+      /* create the .note section if this is the first version string */
+
+      note_secp = bfd_get_section_by_name(stdoutput,".note");
+      if ( note_secp == (asection *)NULL ) {
+             note_secp = bfd_make_section_old_way(stdoutput,".note");
+             bfd_set_section_flags(stdoutput,
+                                   note_secp,
+                                   SEC_LOAD | SEC_ALLOC | SEC_HAS_CONTENTS);
+      }
+
+      /* process the version string */
+
+      subseg_new((char *)note_secp->name, 0);
+      len = strlen(name);
+
+      i_note.namesz    = ((len + 1) + 3) & ~3; /* round this to word boundary  */
+      i_note.descsz    = 0;                    /* no description       */
+      i_note.type      = NT_VERSION;
+      p = frag_more(sizeof(e_note.namesz));
+      md_number_to_chars(p, i_note.namesz, 4);
+      p = frag_more(sizeof(e_note.descsz));
+      md_number_to_chars(p, i_note.descsz, 4);
+      p = frag_more(sizeof(e_note.type));
+      md_number_to_chars(p, i_note.type,   4);
+
+      for ( i = 0; i < len; i++ ) {
+             ch = *(name + i);
+             {
+                     FRAG_APPEND_1_CHAR( ch );
+             }
+      }
+      frag_align(2,0);
+
+      subseg_new((char *)seg->name,subseg);
+    }
+    else {
+      as_bad( "Expected \"-ed string" );
+    }
+    demand_empty_rest_of_line();
+}
+
+static void
+obj_elf_size ()
+{
+  char *name = input_line_pointer;
+  char c = get_symbol_end ();
+  char *p;
+  expressionS exp;
+  segT sec;
+  symbolS *sym;
+
+  p = input_line_pointer;
+  *p = c;
+  SKIP_WHITESPACE ();
+  if (*input_line_pointer != ',')
+    {
+      *p = 0;
+      as_bad ("expected comma after name `%s' in .size directive", name);
+      *p = c;
+      ignore_rest_of_line ();
+      return;
+    }
+  input_line_pointer++;
+  sec = expression (&exp);
+  if (sec == absent_section)
+    {
+      as_bad ("missing expression in .size directive");
+      exp.X_seg = absolute_section;
+      exp.X_add_number = 0;
+    }
+  *p = 0;
+  sym = symbol_find_or_make (name);
+  *p = c;
+  if (sec == absolute_section)
+    S_SET_SIZE (sym, exp.X_add_number);
+  else
+    as_tsktsk (".size not yet supported, ignored");
+  demand_empty_rest_of_line ();
+}
+
+static void
+obj_elf_type ()
+{
+  char *name = input_line_pointer;
+  char c = get_symbol_end ();
+  char *p;
+  int type;
+  symbolS *sym;
+
+  p = input_line_pointer;
+  *p = c;
+  SKIP_WHITESPACE ();
+  if (*input_line_pointer != ',')
+    {
+      as_bad ("expected comma after name in .type directive");
+    egress:
+      ignore_rest_of_line ();
+      return;
+    }
+  input_line_pointer++;
+  SKIP_WHITESPACE ();
+  if (*input_line_pointer != '#')
+    {
+      as_bad ("expected `#' after comma in .type directive");
+      goto egress;
+    }
+  input_line_pointer++;
+  if (!strncmp ("function", input_line_pointer, sizeof ("function") - 1))
+    {
+      type = BSF_FUNCTION;
+      input_line_pointer += sizeof ("function") - 1;
+    }
+  else
+    {
+      as_bad ("unrecognized symbol type, ignored");
+      goto egress;
+    }
+  demand_empty_rest_of_line ();
+  *p = 0;
+  sym = symbol_find_or_make (name);
+  sym->bsym->flags = type;
+}
+
+static void
+obj_elf_ident ()
+{
+  int xxx;
+  char * string;
+
+  string = demand_copy_C_string (&xxx);
+  as_tsktsk (".ident not supported, ignoring");
+}
index dd13b62c6f03da518e518e6c9b41cc565865276a..0a9c22af61d1b378a039c1ceeeb85ffa1a8ee9ba 100644 (file)
@@ -98,12 +98,12 @@ int md_short_jump_size = 4;
 int md_long_jump_size = 4;
 #if defined(BFD_HEADERS)
 #ifdef RELSZ
-int md_reloc_size = RELSZ;     /* Coff headers */
+const int md_reloc_size = RELSZ;       /* Coff headers */
 #else
-int md_reloc_size = 12;                /* something else headers */
+const int md_reloc_size = 12;          /* something else headers */
 #endif
 #else
-int md_reloc_size = 12;                /* Not bfdized*/
+const int md_reloc_size = 12;          /* Not bfdized*/
 #endif
 
 /* This array holds the chars that always start a comment.  If the
index 4cd741d65b4b51a90fc3c795b074f23c4d48bf34..0379f7176cf4aa66abeae8f45e54353db3c3ca1b 100644 (file)
@@ -58,7 +58,7 @@ const pseudo_typeS md_pseudo_table[] =
   {0, 0, 0}
 };
 
-int md_reloc_size;
+const int md_reloc_size;
 
 const char EXP_CHARS[] = "eE";
 
index 0a6b57302b39a67a040636480ed34cf168cb8b1c..0f5d2186ed3a1c9075c5003a28bfd9b6e08c1520 100644 (file)
@@ -27,7 +27,6 @@
 #include <ctype.h>
 
 #include "as.h"
-#include "read.h"
 
 #include "obstack.h"
 #include "opcode/i386.h"
@@ -46,13 +45,14 @@ typedef struct
     /* OPERANDS gives the number of given operands. */
     unsigned int operands;
 
-    /* REG_OPERANDS, DISP_OPERANDS, MEM_OPERANDS, IMM_OPERANDS give the number of
-          given register, displacement, memory operands and immediate operands. */
+    /* REG_OPERANDS, DISP_OPERANDS, MEM_OPERANDS, IMM_OPERANDS give the number
+       of given register, displacement, memory operands and immediate
+       operands. */
     unsigned int reg_operands, disp_operands, mem_operands, imm_operands;
 
     /* TYPES [i] is the type (see above #defines) which tells us how to
-          search through DISPS [i] & IMMS [i] & REGS [i] for the required
-          operand. */
+       search through DISPS [i] & IMMS [i] & REGS [i] for the required
+       operand.  */
     unsigned int types[MAX_OPERANDS];
 
     /* Displacements (if given) for each operand. */
@@ -65,23 +65,23 @@ typedef struct
     reg_entry *regs[MAX_OPERANDS];
 
     /* BASE_REG, INDEX_REG, and LOG2_SCALE_FACTOR are used to encode
-          the base index byte below.  */
+       the base index byte below.  */
     reg_entry *base_reg;
     reg_entry *index_reg;
     unsigned int log2_scale_factor;
 
     /* SEG gives the seg_entry of this insn.  It is equal to zero unless
-          an explicit segment override is given. */
+       an explicit segment override is given. */
     const seg_entry *seg;      /* segment for memory operands (if given) */
 
     /* PREFIX holds all the given prefix opcodes (usually null).
-          PREFIXES is the size of PREFIX. */
+       PREFIXES is the size of PREFIX. */
     /* richfix: really unsigned? */
     unsigned char prefix[MAX_PREFIXES];
     unsigned int prefixes;
 
-    /* RM and IB are the modrm byte and the base index byte where the addressing
-          modes of this insn are encoded. */
+    /* RM and IB are the modrm byte and the base index byte where the
+       addressing modes of this insn are encoded. */
 
     modrm_byte rm;
     base_index_byte bi;
@@ -91,7 +91,11 @@ i386_insn;
 
 /* This array holds the chars that always start a comment.  If the
    pre-processor is disabled, these aren't very useful */
+#ifdef TE_I386AIX
+const char comment_chars[] = "#/";
+#else
 const char comment_chars[] = "#";
+#endif
 
 /* This array holds the chars that only start a comment at the beginning of
    a line.  If the line seems to have the form '# 123 filename'
@@ -176,70 +180,108 @@ static int this_operand; /* current operand we are working on */
 
 const relax_typeS md_relax_table[] =
 {
-/*
-         The fields are:
-         1) most positive reach of this state,
-         2) most negative reach of this state,
-         3) how many bytes this mode will add to the size of the current frag
-         4) which index into the table to try if we can't fit into this one.
-         */
+/* The fields are:
+   1) most positive reach of this state,
+   2) most negative reach of this state,
+   3) how many bytes this mode will add to the size of the current frag
+   4) which index into the table to try if we can't fit into this one.
+   */
   {1, 1, 0, 0},
   {1, 1, 0, 0},
   {1, 1, 0, 0},
   {1, 1, 0, 0},
 
 /* For now we don't use word displacement jumps:  they may be
-          untrustworthy. */
+   untrustworthy. */
   {127 + 1, -128 + 1, 0, ENCODE_RELAX_STATE (COND_JUMP, DWORD)},
 /* word conditionals add 3 bytes to frag:
-          2 opcode prefix; 1 displacement bytes */
+   2 opcode prefix; 1 displacement bytes */
   {32767 + 2, -32768 + 2, 3, ENCODE_RELAX_STATE (COND_JUMP, DWORD)},
 /* dword conditionals adds 4 bytes to frag:
-          1 opcode prefix; 3 displacement bytes */
+   1 opcode prefix; 3 displacement bytes */
   {0, 0, 4, 0},
   {1, 1, 0, 0},
 
   {127 + 1, -128 + 1, 0, ENCODE_RELAX_STATE (UNCOND_JUMP, DWORD)},
 /* word jmp adds 2 bytes to frag:
-          1 opcode prefix; 1 displacement bytes */
+   1 opcode prefix; 1 displacement bytes */
   {32767 + 2, -32768 + 2, 2, ENCODE_RELAX_STATE (UNCOND_JUMP, DWORD)},
 /* dword jmp adds 3 bytes to frag:
-          0 opcode prefix; 3 displacement bytes */
+   0 opcode prefix; 3 displacement bytes */
   {0, 0, 3, 0},
   {1, 1, 0, 0},
 
 };
 
-#if __STDC__ == 1
-
-static char *output_invalid (int c);
-static int fits_in_signed_byte (long num);
-static int fits_in_signed_word (long num);
-static int fits_in_unsigned_byte (long num);
-static int fits_in_unsigned_word (long num);
-static int i386_operand (char *operand_string);
-static int smallest_imm_type (long num);
-static reg_entry *parse_register (char *reg_string);
-static unsigned long mode_from_disp_size (unsigned long t);
-static unsigned long opcode_suffix_to_type (unsigned long s);
-static void s_bss (void);
-
-#else /* not __STDC__ */
-
-static char *output_invalid ();
-static int fits_in_signed_byte ();
-static int fits_in_signed_word ();
-static int fits_in_unsigned_byte ();
-static int fits_in_unsigned_word ();
-static int i386_operand ();
-static int smallest_imm_type ();
-static reg_entry *parse_register ();
-static unsigned long mode_from_disp_size ();
-static unsigned long opcode_suffix_to_type ();
-static void s_bss ();
-
-#endif /* not __STDC__ */
+static char *output_invalid PARAMS ((int c));
+static int i386_operand PARAMS ((char *operand_string));
+static reg_entry *parse_register PARAMS ((char *reg_string));
+#ifndef I386COFF
+static void s_bss PARAMS ((void));
+#endif
 
+static unsigned long
+mode_from_disp_size (t)
+     unsigned long t;
+{
+  return ((t & (Disp8))
+         ? 1
+         : ((t & (Disp32)) ? 2 : 0));
+}                              /* mode_from_disp_size() */
+
+/* convert opcode suffix ('b' 'w' 'l' typically) into type specifyer */
+
+static unsigned long
+opcode_suffix_to_type (s)
+     unsigned long s;
+{
+  return (s == BYTE_OPCODE_SUFFIX
+         ? Byte : (s == WORD_OPCODE_SUFFIX
+                   ? Word : DWord));
+}                              /* opcode_suffix_to_type() */
+
+static int
+fits_in_signed_byte (num)
+     long num;
+{
+  return ((num >= -128) && (num <= 127));
+}                              /* fits_in_signed_byte() */
+
+static int
+fits_in_unsigned_byte (num)
+     long num;
+{
+  return ((num & 0xff) == num);
+}                              /* fits_in_unsigned_byte() */
+
+static int
+fits_in_unsigned_word (num)
+     long num;
+{
+  return ((num & 0xffff) == num);
+}                              /* fits_in_unsigned_word() */
+
+static int
+fits_in_signed_word (num)
+     long num;
+{
+  return ((-32768 <= num) && (num <= 32767));
+}                              /* fits_in_signed_word() */
+
+static int
+smallest_imm_type (num)
+     long num;
+{
+  return ((num == 1)
+         ? (Imm1 | Imm8 | Imm8S | Imm16 | Imm32)
+         : (fits_in_signed_byte (num)
+            ? (Imm8S | Imm8 | Imm16 | Imm32)
+            : (fits_in_unsigned_byte (num)
+               ? (Imm8 | Imm16 | Imm32)
+               : ((fits_in_signed_word (num) || fits_in_unsigned_word (num))
+                  ? (Imm16 | Imm32)
+                  : (Imm32)))));
+}                              /* smallest_imm_type() */
 
 /* Ignore certain directives generated by gcc. This probably should
    not be here. */
@@ -252,12 +294,20 @@ dummy ()
 
 const pseudo_typeS md_pseudo_table[] =
 {
+#ifndef I386COFF
   {"bss", s_bss, 0},
+#endif
+#if !defined (TE_LINUX) && !defined (TE_386BSD)
   {"align", s_align_bytes, 0},
+#else
+  {"align", s_align_ptwo, 0},
+#endif
   {"ffloat", float_cons, 'f'},
   {"dfloat", float_cons, 'd'},
   {"tfloat", float_cons, 'x'},
   {"value", cons, 2},
+  {"noopt", s_ignore, 0},
+  {"optim", s_ignore, 0},
   {0, 0, 0}
 };
 
@@ -305,9 +355,9 @@ md_begin ()
        else
          {
            /* different name --> ship out current template list;
-                                  add to hash table; & begin anew */
-           /* Note: end must be set before start! since obstack_next_free changes
-                                  upon opstack_finish */
+              add to hash table; & begin anew */
+           /* Note: end must be set before start! since obstack_next_free
+              changes upon opstack_finish */
            core_optab->end = (template *) obstack_next_free (&o);
            core_optab->start = (template *) obstack_finish (&o);
            hash_err = hash_insert (op_hash, prev_name, (char *) core_optab);
@@ -554,11 +604,33 @@ pt (t)
 
 #endif /* DEBUG386 */
 \f
-/*
-  This is the guts of the machine-dependent assembler.  LINE points to a
-  machine dependent instruction.  This funciton is supposed to emit
-  the frags/bytes it assembles to.
-  */
+#ifdef BFD_ASSEMBLER
+static bfd_reloc_code_real_type
+reloc (size, pcrel)
+     int size;
+     int pcrel;
+{
+  if (pcrel)
+    switch (size)
+      {
+      case 1: return BFD_RELOC_8_PCREL;
+      case 2: return BFD_RELOC_16_PCREL;
+      case 4: return BFD_RELOC_32_PCREL;
+      }
+  else
+    switch (size)
+      {
+      case 1: return BFD_RELOC_8;
+      case 2: return BFD_RELOC_16;
+      case 4: return BFD_RELOC_32;
+      }
+  abort ();
+}
+#endif
+
+/* This is the guts of the machine-dependent assembler.  LINE points to a
+   machine dependent instruction.  This funciton is supposed to emit
+   the frags/bytes it assembles to.  */
 void
 md_assemble (line)
      char *line;
@@ -576,8 +648,8 @@ md_assemble (line)
   save_stack_p = save_stack;   /* reset stack pointer */
 
   /* Fist parse an opcode & call i386_operand for the operands.
-          We assume that the scrubber has arranged it so that line[0] is the valid
-          start of a (possibly prefixed) opcode. */
+     We assume that the scrubber has arranged it so that line[0] is the valid
+     start of a (possibly prefixed) opcode. */
   {
     register char *l = line;   /* Fast place to put LINE. */
 
@@ -646,7 +718,7 @@ md_assemble (line)
       }
 
     /* Lookup insn in hash; try intel & att naming conventions if appropriate;
-                  that is:  we only use the opcode suffix 'b' 'w' or 'l' if we need to. */
+       that is:  we only use the opcode suffix 'b' 'w' or 'l' if we need to. */
     current_templates = (templates *) hash_find (op_hash, token_start);
     if (!current_templates)
       {
@@ -786,8 +858,10 @@ md_assemble (line)
 
 #define MATCH(overlap,given_type) \
        (overlap && \
-        (overlap & (JumpAbsolute|BaseIndex|Mem8)) \
-        == (given_type & (JumpAbsolute|BaseIndex|Mem8)))
+        (((overlap & (JumpAbsolute|BaseIndex|Mem8)) \
+          == (given_type & (JumpAbsolute|BaseIndex|Mem8))) \
+         || (overlap == InOutPortReg)))
+
 
   /* If m0 and m1 are register matches they must be consistent
      with the expected operand types t0 and t1.
@@ -1090,11 +1164,13 @@ md_assemble (line)
                    unsigned int fake_zero_displacement = 0;
                    unsigned int o = (i.types[0] & Mem) ? 0 : ((i.types[1] & Mem) ? 1 : 2);
 
-                   /* Encode memory operand into modrm byte and base index byte. */
+                   /* Encode memory operand into modrm byte and base index
+                      byte. */
 
                    if (i.base_reg == esp && !i.index_reg)
                      {
-                       /* <disp>(%esp) becomes two byte modrm with no index register. */
+                       /* <disp>(%esp) becomes two byte modrm with no index
+                          register. */
                        i.rm.regmem = ESCAPE_TO_TWO_BYTE_ADDRESSING;
                        i.rm.mode = mode_from_disp_size (i.types[o]);
                        i.bi.base = ESP_REG_NUM;
@@ -1105,8 +1181,8 @@ md_assemble (line)
                      {
                        if (!(i.types[o] & Disp))
                          {
-                           /* Must fake a zero byte displacement.
-                                                                          There is no direct way to code '(%ebp)' directly. */
+                           /* Must fake a zero byte displacement.  There is
+                              no direct way to code '(%ebp)' directly. */
                            fake_zero_displacement = 1;
                            /* fake_zero_displacement code does not set this. */
                            i.types[o] |= Disp8;
@@ -1173,7 +1249,7 @@ md_assemble (line)
                           holds the correct displacement size. */
                        exp = &disp_expressions[i.disp_operands++];
                        i.disps[o] = exp;
-                       exp->X_seg = SEG_ABSOLUTE;
+                       exp->X_seg = absolute_section;
                        exp->X_add_number = 0;
                        exp->X_add_symbol = (symbolS *) 0;
                        exp->X_subtract_symbol = (symbolS *) 0;
@@ -1256,25 +1332,27 @@ md_assemble (line)
     if (t->opcode_modifier & Jump)
       {
        int n = i.disps[0]->X_add_number;
+       segT seg;
 
-       switch (i.disps[0]->X_seg)
+       seg = i.disps[0]->X_seg;
+
+       if (seg == absolute_section)
          {
-         case SEG_ABSOLUTE:
            if (fits_in_signed_byte (n))
              {
                p = frag_more (2);
                p[0] = t->base_opcode;
                p[1] = n;
-#if 0                          /* leave out 16 bit jumps - pace */
              }
+#if 0                          /* leave out 16 bit jumps - pace */
            else if (fits_in_signed_word (n))
              {
                p = frag_more (4);
                p[0] = WORD_PREFIX_OPCODE;
                p[1] = t->base_opcode;
                md_number_to_chars (&p[2], n, 2);
-#endif
              }
+#endif
            else
              {                 /* It's an absolute dword displacement. */
                if (t->base_opcode == JUMP_PC_RELATIVE)
@@ -1293,13 +1371,12 @@ md_assemble (line)
                    md_number_to_chars (&p[2], n, 4);
                  }
              }
-           break;
-         default:
+         }
+       else
+         {
            /* It's a symbol; end frag & setup for relax.
-              Make sure there are 6 chars left in the current frag; if not
-              we'll have to start a new one. */
-           /* I caught it failing with obstack_room == 6,
-              so I changed to <=   pace */
+              Make sure there are more than 6 chars left in the current frag;
+              if not we'll have to start a new one. */
            if (obstack_room (&frags) <= 6)
              {
                frag_wane (frag_now);
@@ -1315,7 +1392,6 @@ md_assemble (line)
                       : ENCODE_RELAX_STATE (COND_JUMP, BYTE)),
                      i.disps[0]->X_add_symbol,
                      n, p);
-           break;
          }
       }
     else if (t->opcode_modifier & (JumpByte | JumpDword))
@@ -1336,35 +1412,34 @@ md_assemble (line)
          }
 
        p = frag_more (size);
-       switch (i.disps[0]->X_seg)
+       if (i.disps[0]->X_seg == absolute_section)
          {
-         case SEG_ABSOLUTE:
            md_number_to_chars (p, n, size);
            if (size == 1 && !fits_in_signed_byte (n))
              {
                as_bad ("loop/jecx only takes byte displacement; %d shortened to %d",
                        n, *p);
              }
-           break;
-         default:
+         }
+       else
+         {
            fix_new (frag_now, p - frag_now->fr_literal, size,
                     i.disps[0]->X_add_symbol, i.disps[0]->X_subtract_symbol,
                     i.disps[0]->X_add_number, 1, NO_RELOC);
-           break;
          }
       }
     else if (t->opcode_modifier & JumpInterSegment)
       {
        p = frag_more (1 + 2 + 4);      /* 1 opcode; 2 segment; 4 offset */
        p[0] = t->base_opcode;
-       if (i.imms[1]->X_seg == SEG_ABSOLUTE)
+       if (i.imms[1]->X_seg == absolute_section)
          md_number_to_chars (p + 1, i.imms[1]->X_add_number, 4);
        else
          fix_new (frag_now, p + 1 - frag_now->fr_literal, 4,
                   i.imms[1]->X_add_symbol,
                   i.imms[1]->X_subtract_symbol,
                   i.imms[1]->X_add_number, 0, NO_RELOC);
-       if (i.imms[0]->X_seg != SEG_ABSOLUTE)
+       if (i.imms[0]->X_seg != absolute_section)
          as_bad ("can't handle non absolute segment in long call/jmp");
        md_number_to_chars (p + 5, i.imms[0]->X_add_number, 2);
       }
@@ -1430,7 +1505,7 @@ md_assemble (line)
              {
                if (i.disps[n])
                  {
-                   if (i.disps[n]->X_seg == SEG_ABSOLUTE)
+                   if (i.disps[n]->X_seg == absolute_section)
                      {
                        if (i.types[n] & (Disp8 | Abs8))
                          {
@@ -1449,7 +1524,7 @@ md_assemble (line)
                          }
                      }
                    else
-                     {         /* not SEG_ABSOLUTE */
+                     {         /* not absolute_section */
                        /* need a 32-bit fixup (don't support 8bit non-absolute disps) */
                        p = frag_more (4);
                        fix_new (frag_now, p - frag_now->fr_literal, 4,
@@ -1469,7 +1544,7 @@ md_assemble (line)
              {
                if (i.imms[n])
                  {
-                   if (i.imms[n]->X_seg == SEG_ABSOLUTE)
+                   if (i.imms[n]->X_seg == absolute_section)
                      {
                        if (i.types[n] & (Imm8 | Imm8S))
                          {
@@ -1488,7 +1563,7 @@ md_assemble (line)
                          }
                      }
                    else
-                     {         /* not SEG_ABSOLUTE */
+                     {         /* not absolute_section */
                        /* need a 32-bit fixup (don't support 8bit non-absolute ims) */
                        /* try to support other sizes ... */
                        int size;
@@ -1600,7 +1675,7 @@ i386_operand (operand_string)
   else if (*op_string == IMMEDIATE_PREFIX)
     {                          /* ... or an immediate */
       char *save_input_line_pointer;
-      segT exp_seg = SEG_GOOF;
+      segT exp_seg = 0;
       expressionS *exp;
 
       if (i.imm_operands == MAX_IMMEDIATE_OPERANDS)
@@ -1616,36 +1691,46 @@ i386_operand (operand_string)
       exp_seg = expression (exp);
       input_line_pointer = save_input_line_pointer;
 
-      switch (exp_seg)
+      if (exp_seg == absent_section)
        {
-       case SEG_ABSENT:        /* missing or bad expr becomes absolute 0 */
+         /* missing or bad expr becomes absolute 0 */
          as_bad ("missing or invalid immediate expression '%s' taken as 0",
                  operand_string);
-         exp->X_seg = SEG_ABSOLUTE;
+         exp->X_seg = absolute_section;
          exp->X_add_number = 0;
          exp->X_add_symbol = (symbolS *) 0;
          exp->X_subtract_symbol = (symbolS *) 0;
          i.types[this_operand] |= Imm;
-         break;
-       case SEG_ABSOLUTE:
+       }
+      else if (exp_seg == absolute_section)
+       {
          i.types[this_operand] |= smallest_imm_type (exp->X_add_number);
-         break;
-       case SEG_TEXT:
-       case SEG_DATA:
-       case SEG_BSS:
-       case SEG_UNKNOWN:
-         i.types[this_operand] |= Imm32;       /* this is an address ==> 32bit */
-         break;
-       default:
+       }
+#ifndef I386COFF
+      else if (exp_seg != text_section
+              && exp_seg != data_section
+              && exp_seg != bss_section
+              && exp_seg != undefined_section
+#ifdef BFD_ASSEMBLER
+              && ! bfd_is_com_section (exp_seg)
+#endif
+              )
+       {
        seg_unimplemented:
          as_bad ("Unimplemented segment type %d in parse_operand", exp_seg);
          return 0;
        }
+#endif
+      else
+       {
+         /* this is an address ==> 32bit */
+         i.types[this_operand] |= Imm32;
+       }
       /* shorten this type of this operand if the instruction wants
-                * fewer bits than are present in the immediate.  The bit field
-                * code can put out 'andb $0xffffff, %al', for example.   pace
-                * also 'movw $foo,(%eax)'
-                */
+       * fewer bits than are present in the immediate.  The bit field
+       * code can put out 'andb $0xffffff, %al', for example.   pace
+       * also 'movw $foo,(%eax)'
+       */
       switch (i.suffix)
        {
        case WORD_OPCODE_SUFFIX:
@@ -1686,17 +1771,17 @@ i386_operand (operand_string)
          i.types[this_operand] |= Mem32;
        }
 
-      /*  Check for base index form.  We detect the base index form by
-                   looking for an ')' at the end of the operand, searching
-                   for the '(' matching it, and finding a REGISTER_PREFIX or ','
-                   after it. */
+      /* Check for base index form.  We detect the base index form by
+        looking for an ')' at the end of the operand, searching
+        for the '(' matching it, and finding a REGISTER_PREFIX or ','
+        after it. */
       base_string = end_of_operand_string - 1;
       found_base_index_form = 0;
       if (*base_string == ')')
        {
          unsigned int parens_balenced = 1;
-         /* We've already checked that the number of left & right ()'s are equal,
-                          so this loop will not be infinite. */
+         /* We've already checked that the number of left & right ()'s are
+            equal, so this loop will not be infinite. */
          do
            {
              base_string--;
@@ -1712,8 +1797,8 @@ i386_operand (operand_string)
        }
 
       /* If we can't parse a base index register expression, we've found
-                  a pure displacement expression.  We set up displacement_string_start
-                  and displacement_string_end for the code below. */
+        a pure displacement expression.  We set up displacement_string_start
+        and displacement_string_end for the code below. */
       if (!found_base_index_form)
        {
          displacement_string_start = op_string;
@@ -1829,12 +1914,12 @@ i386_operand (operand_string)
        }
 
       /* If there's an expression begining the operand, parse it,
-                  assuming displacement_string_start and displacement_string_end
-                  are meaningful. */
+        assuming displacement_string_start and displacement_string_end
+        are meaningful. */
       if (displacement_string_start)
        {
          register expressionS *exp;
-         segT exp_seg = SEG_GOOF;
+         segT exp_seg = 0;
          char *save_input_line_pointer;
          exp = &disp_expressions[i.disp_operands];
          i.disps[this_operand] = exp;
@@ -1847,29 +1932,35 @@ i386_operand (operand_string)
            as_bad ("Ignoring junk '%s' after expression", input_line_pointer);
          RESTORE_END_STRING (displacement_string_end);
          input_line_pointer = save_input_line_pointer;
-         switch (exp_seg)
+         if (exp_seg == absent_section)
            {
-           case SEG_ABSENT:
              /* missing expr becomes absolute 0 */
              as_bad ("missing or invalid displacement '%s' taken as 0",
                      operand_string);
              i.types[this_operand] |= (Disp | Abs);
-             exp->X_seg = SEG_ABSOLUTE;
+             exp->X_seg = absolute_section;
              exp->X_add_number = 0;
              exp->X_add_symbol = (symbolS *) 0;
              exp->X_subtract_symbol = (symbolS *) 0;
-             break;
-           case SEG_ABSOLUTE:
+           }
+         else if (exp_seg == absolute_section)
+           {
              i.types[this_operand] |= SMALLEST_DISP_TYPE (exp->X_add_number);
-             break;
-           case SEG_TEXT:
-           case SEG_DATA:
-           case SEG_BSS:
-           case SEG_UNKNOWN:   /* must be 32 bit displacement (i.e. address) */
+           }
+         else if (exp_seg == text_section
+                  || exp_seg == data_section
+                  || exp_seg == bss_section
+                  || exp_seg == undefined_section)
+           {
              i.types[this_operand] |= Disp32;
-             break;
-           default:
+           }
+         else
+           {
+#ifdef I386COFF
+             i.types[this_operand] |= Disp32;
+#else
              goto seg_unimplemented;
+#endif
            }
        }
 
@@ -1881,12 +1972,15 @@ i386_operand (operand_string)
          return 0;
        }
       /*
-                * special case for (%dx) while doing input/output op
-                */
+       * special case for (%dx) while doing input/output op
+       */
       if ((i.base_reg &&
           (i.base_reg->reg_type == (Reg16 | InOutPortReg)) &&
           (i.index_reg == 0)))
-       return 1;
+       {
+         i.types[this_operand] |= InOutPortReg;
+         return 1;
+       }
       if ((i.base_reg && (i.base_reg->reg_type & Reg32) == 0) ||
          (i.index_reg && (i.index_reg->reg_type & Reg32) == 0))
        {
@@ -1975,10 +2069,18 @@ md_estimate_size_before_relax (fragP, segment)
  * Out:        Any fixSs and constants are set up.
  *     Caller will turn frag into a ".space 0".
  */
+#ifndef BFD_ASSEMBLER
 void
 md_convert_frag (headers, fragP)
      object_headers *headers;
      register fragS *fragP;
+#else
+void
+md_convert_frag (abfd, sec, fragP)
+     bfd *abfd;
+     segT sec;
+     register fragS *fragP;
+#endif
 {
   register unsigned char *opcode;
   unsigned char *where_to_put_displacement = NULL;
@@ -2049,7 +2151,7 @@ md_convert_frag (headers, fragP)
 
 int md_short_jump_size = 2;    /* size of byte displacement jmp */
 int md_long_jump_size = 5;     /* size of dword displacement jmp */
-int md_reloc_size = 8;         /* Size of relocation record */
+const int md_reloc_size = 8;   /* Size of relocation record */
 
 void
 md_create_short_jump (ptr, from_addr, to_addr, frag, to_symbol)
@@ -2135,8 +2237,8 @@ md_number_to_chars (con, value, nbytes)
    the same (little-endian) format, so we don't need to care about which
    we are handling.  */
 
-void
-md_apply_fix (fixP, value)
+static void
+md_apply_fix_1 (fixP, value)
      fixS *fixP;               /* The fix we're to put in */
      long value;               /* The value of the bits. */
 {
@@ -2162,6 +2264,25 @@ md_apply_fix (fixP, value)
     }
 }
 
+#ifdef BFD_ASSEMBLER
+int
+md_apply_fix (fixP, valp)
+     fixS *fixP;
+     long *valp;
+{
+  md_apply_fix_1 (fixP, *valp);
+  return 1;
+}
+#else
+void
+md_apply_fix (fixP, val)
+     fixS *fixP;
+     long val;
+{
+  md_apply_fix_1 (fixP, val);
+}
+#endif
+
 long                           /* Knows about the byte order in a word. */
 md_chars_to_number (con, nbytes)
      unsigned char con[];      /* Low order byte 1st. */
@@ -2176,64 +2297,6 @@ md_chars_to_number (con, nbytes)
   return retval;
 }
 
-/* Not needed for coff since relocation structure does not
-   contain bitfields. */
-#if defined(OBJ_AOUT) | defined(OBJ_BOUT)
-#ifdef comment
-/* Output relocation information in the target's format.  */
-void
-md_ri_to_chars (the_bytes, ri)
-     char *the_bytes;
-     struct reloc_info_generic *ri;
-{
-  /* this is easy */
-  md_number_to_chars (the_bytes, ri->r_address, 4);
-  /* now the fun stuff */
-  the_bytes[6] = (ri->r_symbolnum >> 16) & 0x0ff;
-  the_bytes[5] = (ri->r_symbolnum >> 8) & 0x0ff;
-  the_bytes[4] = ri->r_symbolnum & 0x0ff;
-  the_bytes[7] = (((ri->r_extern << 3) & 0x08) | ((ri->r_length << 1) & 0x06) |
-                 ((ri->r_pcrel << 0) & 0x01)) & 0x0F;
-}
-
-#endif /* comment */
-
-void
-tc_aout_fix_to_chars (where, fixP, segment_address_in_file)
-     char *where;
-     fixS *fixP;
-     relax_addressT segment_address_in_file;
-{
-  /*
-        * In: length of relocation (or of address) in chars: 1, 2 or 4.
-        * Out: GNU LD relocation length code: 0, 1, or 2.
-        */
-
-  static unsigned char nbytes_r_length[] =
-  {42, 0, 1, 42, 2};
-  long r_symbolnum;
-
-  know (fixP->fx_addsy != NULL);
-
-  md_number_to_chars (where,
-       fixP->fx_frag->fr_address + fixP->fx_where - segment_address_in_file,
-                     4);
-
-  r_symbolnum = (S_IS_DEFINED (fixP->fx_addsy)
-                ? S_GET_TYPE (fixP->fx_addsy)
-                : fixP->fx_addsy->sy_number);
-
-  where[6] = (r_symbolnum >> 16) & 0x0ff;
-  where[5] = (r_symbolnum >> 8) & 0x0ff;
-  where[4] = r_symbolnum & 0x0ff;
-  where[7] = ((((!S_IS_DEFINED (fixP->fx_addsy)) << 3) & 0x08)
-             | ((nbytes_r_length[fixP->fx_size] << 1) & 0x06)
-             | (((fixP->fx_pcrel << 0) & 0x01) & 0x0f));
-
-  return;
-}                              /* tc_aout_fix_to_chars() */
-
-#endif /* OBJ_AOUT or OBJ_BOUT */
 \f
 
 #define MAX_LITTLENUMS 6
@@ -2286,7 +2349,7 @@ md_atof (type, litP, sizeP)
       md_number_to_chars (litP, (long) (*wordP--), sizeof (LITTLENUM_TYPE));
       litP += sizeof (LITTLENUM_TYPE);
     }
-  return "";                   /* Someone should teach Dean about null pointers */
+  return 0;
 }
 \f
 char output_invalid_buf[8];
@@ -2362,85 +2425,103 @@ md_pcrel_from (fixP)
   return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address;
 }
 
-/* these were macros, but I don't trust macros that eval their
-    arguments more than once.  Besides, gcc can static inline them.
-    xoxorich.  */
+#ifndef I386COFF
 
-static unsigned long
-mode_from_disp_size (t)
-     unsigned long t;
+static void
+s_bss ()
 {
-  return ((t & (Disp8))
-         ? 1
-         : ((t & (Disp32)) ? 2 : 0));
-}                              /* mode_from_disp_size() */
+  register int temp;
 
-/* convert opcode suffix ('b' 'w' 'l' typically) into type specifyer */
+  temp = get_absolute_expression ();
+#ifdef BFD_ASSEMBLER
+  subseg_set (bss_section, (subsegT) temp);
+#else
+  subseg_new (bss_section, (subsegT) temp);
+#endif
+  demand_empty_rest_of_line ();
+}
 
-static unsigned long
-opcode_suffix_to_type (s)
-     unsigned long s;
-{
-  return (s == BYTE_OPCODE_SUFFIX
-         ? Byte : (s == WORD_OPCODE_SUFFIX
-                   ? Word : DWord));
-}                              /* opcode_suffix_to_type() */
+#endif
 
-static int
-fits_in_signed_byte (num)
-     long num;
-{
-  return ((num >= -128) && (num <= 127));
-}                              /* fits_in_signed_byte() */
 
-static int
-fits_in_unsigned_byte (num)
-     long num;
-{
-  return ((num & 0xff) == num);
-}                              /* fits_in_unsigned_byte() */
+#ifdef BFD_ASSEMBLER
 
-static int
-fits_in_unsigned_word (num)
-     long num;
+arelent *
+tc_gen_reloc (section, fixp)
+     asection *section;
+     fixS *fixp;
 {
-  return ((num & 0xffff) == num);
-}                              /* fits_in_unsigned_word() */
+  arelent *reloc;
+  bfd_reloc_code_real_type code;
 
-static int
-fits_in_signed_word (num)
-     long num;
-{
-  return ((-32768 <= num) && (num <= 32767));
-}                              /* fits_in_signed_word() */
+#define F(SZ,PCREL)            (((SZ) << 1) + (PCREL))
+  switch (F (fixp->fx_size, fixp->fx_pcrel))
+    {
+#define MAP(SZ,PCREL,TYPE)     case F(SZ,PCREL): code = (TYPE); break
+      MAP (1, 0, BFD_RELOC_8);
+      MAP (2, 0, BFD_RELOC_16);
+      MAP (4, 0, BFD_RELOC_32);
+      MAP (1, 1, BFD_RELOC_8_PCREL);
+      MAP (2, 1, BFD_RELOC_16_PCREL);
+      MAP (4, 1, BFD_RELOC_32_PCREL);
+    default:
+      abort ();
+    }
 
-static int
-smallest_imm_type (num)
-     long num;
-{
-  return ((num == 1)
-         ? (Imm1 | Imm8 | Imm8S | Imm16 | Imm32)
-         : (fits_in_signed_byte (num)
-            ? (Imm8S | Imm8 | Imm16 | Imm32)
-            : (fits_in_unsigned_byte (num)
-               ? (Imm8 | Imm16 | Imm32)
-               : ((fits_in_signed_word (num) || fits_in_unsigned_word (num))
-                  ? (Imm16 | Imm32)
-                  : (Imm32)))));
-}                              /* smallest_imm_type() */
+  reloc = (arelent *) bfd_alloc_by_size_t (stdoutput, sizeof (arelent));
+  assert (reloc != 0);
+  reloc->sym_ptr_ptr = &fixp->fx_addsy->bsym;
+  reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
+  if (fixp->fx_pcrel)
+    reloc->addend = fixp->fx_addnumber;
+  else
+    reloc->addend = 0;
 
-static void
-s_bss ()
+  reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
+  assert (reloc->howto != 0);
+
+  return reloc;
+}
+
+#else /* ! BFD_ASSEMBLER */
+
+#if (defined(OBJ_AOUT) | defined(OBJ_BOUT))
+void
+tc_aout_fix_to_chars (where, fixP, segment_address_in_file)
+     char *where;
+     fixS *fixP;
+     relax_addressT segment_address_in_file;
 {
-  register int temp;
+  /*
+   * In: length of relocation (or of address) in chars: 1, 2 or 4.
+   * Out: GNU LD relocation length code: 0, 1, or 2.
+   */
 
-  temp = get_absolute_expression ();
-  subseg_new (SEG_BSS, (subsegT) temp);
-  demand_empty_rest_of_line ();
+  static unsigned char nbytes_r_length[] =
+  {42, 0, 1, 42, 2};
+  long r_symbolnum;
+
+  know (fixP->fx_addsy != NULL);
+
+  md_number_to_chars (where,
+       fixP->fx_frag->fr_address + fixP->fx_where - segment_address_in_file,
+                     4);
+
+  r_symbolnum = (S_IS_DEFINED (fixP->fx_addsy)
+                ? S_GET_TYPE (fixP->fx_addsy)
+                : fixP->fx_addsy->sy_number);
+
+  where[6] = (r_symbolnum >> 16) & 0x0ff;
+  where[5] = (r_symbolnum >> 8) & 0x0ff;
+  where[4] = r_symbolnum & 0x0ff;
+  where[7] = ((((!S_IS_DEFINED (fixP->fx_addsy)) << 3) & 0x08)
+             | ((nbytes_r_length[fixP->fx_size] << 1) & 0x06)
+             | (((fixP->fx_pcrel << 0) & 0x01) & 0x0f));
 }
 
+#endif /* OBJ_AOUT or OBJ_BOUT */
 
-#ifdef I386COFF
+#if defined (I386COFF)
 
 short
 tc_coff_fix2rtype (fixP)
@@ -2457,6 +2538,18 @@ tc_coff_fix2rtype (fixP)
 
 }
 
-#endif
+int
+tc_coff_sizemachdep (frag)
+     fragS *frag;
+{
+  if (frag->fr_next)
+    return (frag->fr_next->fr_address - frag->fr_address);
+  else
+    return 0;
+}
+
+#endif /* I386COFF */
+
+#endif /* BFD_ASSEMBLER? */
 
 /* end of tc-i386.c */
index 965a6fb55c5c997c497952e0ff35ae85e4a0af26..f916fa72ed593a3bfad5c073e4add572dcb7f39e 100644 (file)
@@ -40,6 +40,7 @@
    included by one source file per executable.  */
 #include "opcode/m68k.h"
 
+#ifndef BFD_ASSEMBLER
 #ifdef TE_SUN
 /* This variable contains the value to write out at the beginning of
    the a.out file.  The 2<<16 means that this is a 68020 file instead
@@ -49,10 +50,11 @@ long omagic = 2 << 16 | OMAGIC;     /* Magic byte for header file */
 #else
 long omagic = OMAGIC;
 #endif
+#endif
 
 /* This array holds the chars that always start a comment.  If the
    pre-processor is disabled, these aren't very useful */
-const char comment_chars[] = "|";
+CONST char comment_chars[] = "|";
 
 /* This array holds the chars that only start a comment at the beginning of
    a line.  If the line seems to have the form '# 123 filename'
@@ -61,25 +63,23 @@ const char comment_chars[] = "|";
    first line of the input file.  This is because the compiler outputs
    #NO_APP at the beginning of its output. */
 /* Also note that comments like this one will always work. */
-const char line_comment_chars[] = "#";
+CONST char line_comment_chars[] = "#";
 
-const char line_separator_chars[] = "";
+CONST char line_separator_chars[] = "";
 
 /* Chars that can be used to separate mant from exp in floating point nums */
-const char EXP_CHARS[] = "eE";
+CONST char EXP_CHARS[] = "eE";
 
-/* Chars that mean this number is a floating point constant */
-/* As in 0f12.456 */
-/* or    0d1.2345e12 */
+/* Chars that mean this number is a floating point constant, as
+   in "0f12.456" or "0d1.2345e12".  */
 
-const char FLT_CHARS[] = "rRsSfFdDxXeEpP";
+CONST char FLT_CHARS[] = "rRsSfFdDxXeEpP";
 
 /* Also be aware that MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT may have to be
    changed in read.c .  Ideally it shouldn't have to know about it at all,
-   but nothing is ideal around here.
-   */
+   but nothing is ideal around here.  */
 
-int md_reloc_size = 8;         /* Size of relocation record */
+const int md_reloc_size = 8;   /* Size of relocation record */
 
 /* Its an arbitrary name:  This means I don't approve of it */
 /* See flames below */
@@ -349,6 +349,11 @@ struct m68k_it
 
 static struct m68k_it the_ins; /* the instruction being assembled */
 
+#define seg(exp)       ((exp)->e_exp.X_seg)
+#define adds(exp)      ((exp)->e_exp.X_add_symbol)
+#define subs(exp)      ((exp)->e_exp.X_subtract_symbol)
+#define offs(exp)      ((exp)->e_exp.X_add_number)
+
 /* Macros for adding things to the m68k_it struct */
 
 #define addword(w)     the_ins.opcode[the_ins.numo++]=(w)
@@ -373,36 +378,38 @@ static struct m68k_it the_ins;    /* the instruction being assembled */
 
 /* The numo+1 kludge is so we can hit the low order byte of the prev word.
    Blecch.  */
-#define add_fix(width,exp,pc_rel) \
-{\
-   the_ins.reloc[the_ins.nrel].n= (((width)=='B') \
-                                  ? (the_ins.numo*2-1) \
-                                  : (((width)=='b') \
-                                     ? ((the_ins.numo-1)*2) \
-                                     : (the_ins.numo*2)));\
-   the_ins.reloc[the_ins.nrel].add=adds((exp));\
-   the_ins.reloc[the_ins.nrel].sub=subs((exp));\
-   the_ins.reloc[the_ins.nrel].off=offs((exp));\
-   the_ins.reloc[the_ins.nrel].wid=width;\
-   the_ins.reloc[the_ins.nrel++].pcrel=pc_rel;\
+static void
+add_fix (width, exp, pc_rel)
+     char width;
+     struct m68k_exp *exp;
+     int pc_rel;
+{
+  the_ins.reloc[the_ins.nrel].n = (((width)=='B')
+                                  ? (the_ins.numo*2-1)
+                                  : (((width)=='b')
+                                     ? ((the_ins.numo-1)*2)
+                                     : (the_ins.numo*2)));
+  the_ins.reloc[the_ins.nrel].add = adds((exp));
+  the_ins.reloc[the_ins.nrel].sub = subs((exp));
+  the_ins.reloc[the_ins.nrel].off = offs((exp));
+  the_ins.reloc[the_ins.nrel].wid = width;
+  the_ins.reloc[the_ins.nrel++].pcrel = pc_rel;
 }
 
-#define add_frag(add,off,type) \
-{\
-   the_ins.fragb[the_ins.nfrag].fragoff=the_ins.numo;\
-   the_ins.fragb[the_ins.nfrag].fadd=add;\
-   the_ins.fragb[the_ins.nfrag].foff=off;\
-   the_ins.fragb[the_ins.nfrag++].fragty=type;\
+static void
+add_frag(add,off,type)
+     symbolS *add;
+     long off;
+     int type;
+{
+  the_ins.fragb[the_ins.nfrag].fragoff=the_ins.numo;
+  the_ins.fragb[the_ins.nfrag].fadd=add;
+  the_ins.fragb[the_ins.nfrag].foff=off;
+  the_ins.fragb[the_ins.nfrag++].fragty=type;
 }
 
 #define isvar(exp)     ((exp) && (adds(exp) || subs(exp)))
 
-#define seg(exp)       ((exp)->e_exp.X_seg)
-#define adds(exp)      ((exp)->e_exp.X_add_symbol)
-#define subs(exp)      ((exp)->e_exp.X_subtract_symbol)
-#define offs(exp)      ((exp)->e_exp.X_add_number)
-
-
 struct m68k_incant
   {
     char *m_operands;
@@ -419,42 +426,21 @@ struct m68k_incant
 #define gettwo(x)      (((x)->m_opcode)&0xffff)
 
 
-#if __STDC__ == 1
-
-static char *crack_operand (char *str, struct m68k_op *opP);
-static int get_num (struct m68k_exp *exp, int ok);
-static int get_regs (int i, char *str, struct m68k_op *opP);
-static int reverse_16_bits (int in);
-static int reverse_8_bits (int in);
-static int try_index (char **s, struct m68k_op *opP);
-static void install_gen_operand (int mode, int val);
-static void install_operand (int mode, int val);
-static void s_bss (void);
-static void s_data1 (void);
-static void s_data2 (void);
-static void s_even (void);
-static void s_proc (void);
-
-#else /* not __STDC__ */
-
-static char *crack_operand ();
-static int get_num ();
-static int get_regs ();
-static int reverse_16_bits ();
-static int reverse_8_bits ();
-static int try_index ();
-static void install_gen_operand ();
-static void install_operand ();
-static void s_bss ();
-void s_align_bytes ();
-static void s_data1 ();
-static void s_data2 ();
-static void s_even ();
-static void s_proc ();
-
-#endif /* not __STDC__ */
-
-static int current_architecture = 0;
+static char *crack_operand PARAMS ((char *str, struct m68k_op *opP));
+static int get_num PARAMS ((struct m68k_exp *exp, int ok));
+static int get_regs PARAMS ((int i, char *str, struct m68k_op *opP));
+static int reverse_16_bits PARAMS ((int in));
+static int reverse_8_bits PARAMS ((int in));
+static int try_index PARAMS ((char **s, struct m68k_op *opP));
+static void install_gen_operand PARAMS ((int mode, int val));
+static void install_operand PARAMS ((int mode, int val));
+static void s_bss PARAMS ((void));
+static void s_data1 PARAMS ((void));
+static void s_data2 PARAMS ((void));
+static void s_even PARAMS ((void));
+static void s_proc PARAMS ((void));
+
+static int current_architecture;
 
 /* BCC68000 is for patching in an extra jmp instruction for long offsets
    on the 68000.  The 68000 doesn't support long branches with branchs */
@@ -462,8 +448,8 @@ static int current_architecture = 0;
 /* This table desribes how you change sizes for the various types of variable
    size expressions.  This version only supports two kinds. */
 
-/* Note that calls to frag_var need to specify the maximum expansion needed */
-/* This is currently 10 bytes for DBCC */
+/* Note that calls to frag_var need to specify the maximum expansion
+   needed; this is currently 10 bytes for DBCC.  */
 
 /* The fields are:
    How far Forward this mode will reach:
@@ -471,8 +457,7 @@ static int current_architecture = 0;
    How many bytes this mode will add to the size of the frag
    Which mode to go to if the offset won't fit in this one
    */
-const relax_typeS
-  md_relax_table[] =
+CONST relax_typeS md_relax_table[] =
 {
   {1, 1, 0, 0},                        /* First entries aren't used */
   {1, 1, 0, 0},                        /* For no good reason except */
@@ -522,7 +507,7 @@ const relax_typeS
    function to call to execute this pseudo-op
    Integer arg to pass to the function
    */
-const pseudo_typeS md_pseudo_table[] =
+CONST pseudo_typeS md_pseudo_table[] =
 {
   {"data1", s_data1, 0},
   {"data2", s_data2, 0},
@@ -542,7 +527,7 @@ const pseudo_typeS md_pseudo_table[] =
    */
 extern void obj_coff_section ();
 
-const pseudo_typeS mote_pseudo_table[] =
+CONST pseudo_typeS mote_pseudo_table[] =
 {
 
   {"dc.l", cons, 4},
@@ -564,9 +549,6 @@ const pseudo_typeS mote_pseudo_table[] =
   0,
 };
 
-/* #define isbyte(x)   ((x)>=-128 && (x)<=127) */
-/* #define isword(x)   ((x)>=-32768 && (x)<=32767) */
-
 #define issbyte(x)     ((x)>=-128 && (x)<=127)
 #define isubyte(x)     ((x)>=0 && (x)<=255)
 #define issword(x)     ((x)>=-32768 && (x)<=32767)
@@ -639,7 +621,7 @@ m68k_reg_parse (ccp)
   symbolP = symbol_find (start);
   *p = c;
 
-  if (symbolP && S_GET_SEGMENT (symbolP) == SEG_REGISTER)
+  if (symbolP && S_GET_SEGMENT (symbolP) == reg_section)
     {
       *ccp = p;
       return S_GET_VALUE (symbolP);
@@ -938,7 +920,7 @@ m68k_ip_op (str, opP)
 
 #ifndef MIT_SYNTAX_ONLY
       /* The operand has no '@'.  Try to parse it using
-                  Motorola syntax.  */
+        Motorola syntax.  */
       /* Logic of the parsing switch(*str):
                   case                 opP->mode =
                   ----                 -----------
@@ -1257,30 +1239,35 @@ m68k_ip_op (str, opP)
              break;
            }
        }
-      /* if(str[-3]==':') {
-                  int siz;
-
-                  switch(str[-2]) {
-                  case 'b':
-                  case 'B':
-                  siz=1;
-                  break;
-                  case 'w':
-                  case 'W':
-                  siz=2;
-                  break;
-                  case 'l':
-                  case 'L':
-                  siz=3;
-                  break;
-                  default:
-                  opP->error="Specified size isn't :w or :l";
-                  return FAIL;
-                  }
-                  opP->con1=add_exp(beg_str,str-4);
-                  opP->con1->e_siz=siz;
-                  } else */
-      opP->con1 = add_exp (beg_str, str - 2);
+#if 0
+      if (str[-3]==':')
+       {
+         int siz;
+
+         switch (str[-2])
+           {
+           case 'b':
+           case 'B':
+             siz=1;
+             break;
+           case 'w':
+           case 'W':
+             siz=2;
+             break;
+           case 'l':
+           case 'L':
+             siz=3;
+             break;
+           default:
+             opP->error="Specified size isn't :w or :l";
+             return FAIL;
+           }
+         opP->con1=add_exp(beg_str,str-4);
+         opP->con1->e_siz=siz;
+       }
+      else
+#endif
+       opP->con1 = add_exp (beg_str, str - 2);
       /* Should be offset,reg */
       if (str[-1] == ',')
        {
@@ -1412,7 +1399,7 @@ m68k_ip_op (str, opP)
 }                              /* m68k_ip_op() */
 
 
-#ifdef M68KCOFF
+#if defined (M68KCOFF) && !defined (BFD_ASSEMBLER)
 
 short
 tc_coff_fix2rtype (fixP)
@@ -1431,6 +1418,47 @@ tc_coff_fix2rtype (fixP)
 
 #endif
 
+#ifdef BFD_ASSEMBLER
+
+arelent *
+tc_gen_reloc (section, fixp)
+     asection *section;
+     fixS *fixp;
+{
+  arelent *reloc;
+  bfd_reloc_code_real_type code;
+
+#define F(SZ,PCREL)            (((SZ) << 1) + (PCREL))
+  switch (F (fixp->fx_size, fixp->fx_pcrel))
+    {
+#define MAP(SZ,PCREL,TYPE)     case F(SZ,PCREL): code = (TYPE); break
+      MAP (1, 0, BFD_RELOC_8);
+      MAP (2, 0, BFD_RELOC_16);
+      MAP (4, 0, BFD_RELOC_32);
+      MAP (1, 1, BFD_RELOC_8_PCREL);
+      MAP (2, 1, BFD_RELOC_16_PCREL);
+      MAP (4, 1, BFD_RELOC_32_PCREL);
+    default:
+      abort ();
+    }
+
+  reloc = (arelent *) bfd_alloc_by_size_t (stdoutput, sizeof (arelent));
+  assert (reloc != 0);
+  reloc->sym_ptr_ptr = &fixp->fx_addsy->bsym;
+  reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
+  if (fixp->fx_pcrel)
+    reloc->addend = fixp->fx_addnumber;
+  else
+    reloc->addend = 0;
+
+  reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
+  assert (reloc->howto != 0);
+
+  return reloc;
+}
+
+#endif /* BFD_ASSEMBLER */
+
 #ifdef TEST1                   /* TEST1 tests m68k_ip_op(), which parses operands */
 main ()
 {
@@ -1460,9 +1488,9 @@ main ()
 #endif
 
 
-static struct hash_control *op_hash = NULL;    /* handle of the OPCODE hash table
-                                                  NULL means any use before m68k_ip_begin()
-                                                  will crash */
+/* Handle of the OPCODE hash table.  NULL means any use before
+   m68k_ip_begin() will crash.  */
+static struct hash_control *op_hash;
 \f
 
 /*
@@ -1614,9 +1642,8 @@ m68k_ip (instring)
   /* We've got the operands.  Find an opcode that'll accept them */
   for (losing = 0;;)
     {
-      /* if we didn't get the right number of ops,
-       or we have no common model with this pattern
-       then reject this pattern. */
+      /* If we didn't get the right number of ops, or we have no
+        common model with this pattern then reject this pattern. */
 
       if (opsfound != opcode->m_opnum
          || ((opcode->m_arch & current_architecture) == 0))
@@ -1629,11 +1656,11 @@ m68k_ip (instring)
          for (s = opcode->m_operands, opP = &the_ins.operands[0]; *s && !losing; s += 2, opP++)
            {
              /* Warning: this switch is huge! */
-             /* I've tried to organize the cases into  this order:
-          non-alpha first, then alpha by letter.  lower-case goes directly
-          before uppercase counterpart. */
-             /* Code with multiple case ...: gets sorted by the lowest case ...
-          it belongs to.  I hope this makes sense. */
+             /* I've tried to organize the cases into this order:
+                non-alpha first, then alpha by letter.  Lower-case
+                goes directly before uppercase counterpart.  */
+             /* Code with multiple case ...: gets sorted by the lowest
+                case ... it belongs to.  I hope this makes sense.  */
              switch (*s)
                {
                case '!':
@@ -1854,8 +1881,10 @@ m68k_ip (instring)
                    {
                      long t;
 
-                     t = get_num (opP->con1, 80);
-                     if (!issbyte (t) || isvar (opP->con1))
+                     t = get_num (opP->con1, 0);
+                     if (!issbyte (t)
+                         || isvar (opP->con1)
+                         || seg (opP->con1) != absolute_section)
                        losing++;
                    }
                  break;
@@ -2032,10 +2061,10 @@ m68k_ip (instring)
                default:
                  {
                    int got_one = 0, idx;
-                   const static struct
+                   CONST static struct
                      {
                        int arch;
-                       const char *name;
+                       CONST char *name;
                      }
                    archs[] =
                    {
@@ -2113,7 +2142,7 @@ m68k_ip (instring)
              if (strchr ("bwl", s[1]))
                nextword = get_num (opP->con1, 80);
              else
-               nextword = nextword = get_num (opP->con1, 0);
+               nextword = get_num (opP->con1, 0);
              if (isvar (opP->con1))
                add_fix (s[1], opP->con1, 0);
              switch (s[1])
@@ -2170,7 +2199,7 @@ m68k_ip (instring)
                  break;
                }               /* Its BIG */
 #else
-             if (seg (opP->con1) != SEG_BIG)
+             if (seg (opP->con1) != big_section)
                {
                  abort ();
                }
@@ -2278,8 +2307,8 @@ m68k_ip (instring)
              nextword = 0;
              baseo = get_num (opP->con1, 80);
              outro = get_num (opP->con2, 80);
-             /* Figure out the 'addressing mode' */
-             /* Also turn on the BASE_DISABLE bit, if needed */
+             /* Figure out the `addressing mode'.
+                Also turn on the BASE_DISABLE bit, if needed.  */
              if (opP->reg == PC || opP->reg == ZPC)
                {
                  tmpreg = 0x3b;/* 7.3 */
@@ -2321,13 +2350,13 @@ m68k_ip (instring)
                      as_fatal ("failed sanity check.");
                    }
                  /* IF its simple,
-            GET US OUT OF HERE! */
+                    GET US OUT OF HERE! */
 
                  /* Must be INDEX, with an index
-            register.  Address register
-            cannot be ZERO-PC, and either
-            :b was forced, or we know
-            it will fit */
+                    register.  Address register
+                    cannot be ZERO-PC, and either
+                    :b was forced, or we know
+                    it will fit */
                  if (opP->mode == AINDX
                      && opP->reg != FAIL
                      && opP->reg != ZPC
@@ -2345,11 +2374,10 @@ m68k_ip (instring)
              else
                nextword |= 0x40;       /* No index reg */
 
-             /* It aint simple */
+             /* It isn't simple.  */
              nextword |= 0x100;
-             /* If the guy specified a width, we assume that
-          it is wide enough.  Maybe it isn't.  If so, we lose
-          */
+             /* If the guy specified a width, we assume that it is
+                wide enough.  Maybe it isn't.  If so, we lose.  */
              switch (siz1)
                {
                case 0:
@@ -2460,8 +2488,8 @@ m68k_ip (instring)
             on 68010 and 68000 */
                  if (isvar (opP->con1)
                      && !subs (opP->con1)
-                     && seg (opP->con1) == SEG_TEXT
-                     && now_seg == SEG_TEXT
+                     && seg (opP->con1) == text_section
+                     && now_seg == text_section
                      && cpu_of_arch (current_architecture) >= m68020
                      && !flagseen['S']
                      && !strchr ("~%&$?", s[0]))
@@ -2615,6 +2643,7 @@ m68k_ip (instring)
            case 'w':
              if (isvar (opP->con1))
                {
+#if 1
                  /* check for DBcc instruction */
                  if ((the_ins.opcode[0] & 0xf0f8) == 0x50c8)
                    {
@@ -2623,7 +2652,7 @@ m68k_ip (instring)
                      add_frag (adds (opP->con1), offs (opP->con1), TAB (DBCC, SZ_UNDEF));
                      break;
                    }
-
+#endif
                  /* Don't ask! */
                  opP->con1->e_exp.X_add_number += 2;
                  add_fix ('w', opP->con1, 1);
@@ -3342,6 +3371,7 @@ insert_reg (regname, regnum)
 {
   char buf[100];
   int i;
+symbolS *s;
 
 #ifdef REGISTER_PREFIX
   buf[0] = REGISTER_PREFIX;
@@ -3349,22 +3379,25 @@ insert_reg (regname, regnum)
   regname = buf;
 #endif
 
-  symbol_table_insert (symbol_new (regname, SEG_REGISTER, regnum, &zero_address_frag));
+  symbol_table_insert (s = symbol_new (regname, reg_section, regnum, &zero_address_frag));
+
+verify_symbol_chain_2 (s);
 
   for (i = 0; regname[i]; i++)
     buf[i] = islower (regname[i]) ? toupper (regname[i]) : regname[i];
   buf[i] = '\0';
 
-  symbol_table_insert (symbol_new (buf, SEG_REGISTER, regnum, &zero_address_frag));
+  symbol_table_insert (s = symbol_new (buf, reg_section, regnum, &zero_address_frag));
+verify_symbol_chain_2 (s);
 }
 
-static const struct
+struct init_entry
   {
     char *name;
     int number;
-  }
+  };
 
-init_table[] =
+static CONST struct init_entry init_table[] =
 {
   "d0", DATA0,
   "d1", DATA1,
@@ -3582,7 +3615,8 @@ md_assemble (str)
     }
 
   if (the_ins.nfrag == 0)
-    {                          /* No frag hacking involved; just put it out */
+    {
+      /* No frag hacking involved; just put it out */
       toP = frag_more (2 * the_ins.numo);
       fromP = &the_ins.opcode[0];
       for (m = the_ins.numo; m; --m)
@@ -3612,7 +3646,8 @@ md_assemble (str)
              n = 4;
              break;
            default:
-             as_fatal ("Don't know how to figure width of %c in md_assemble()", the_ins.reloc[m].wid);
+             as_fatal ("Don't know how to figure width of %c in md_assemble()",
+                       the_ins.reloc[m].wid);
            }
 
          fix_new (frag_now,
@@ -3648,9 +3683,9 @@ md_assemble (str)
        }
       for (m = 0; m < the_ins.nrel; m++)
        {
-         if ((the_ins.reloc[m].n) >= 2 * shorts_this_frag /* 2*the_ins.fragb[n].fragoff */ )
+         if ((the_ins.reloc[m].n) >= 2 * shorts_this_frag)
            {
-             the_ins.reloc[m].n -= 2 * shorts_this_frag /* 2*the_ins.fragb[n].fragoff */ ;
+             the_ins.reloc[m].n -= 2 * shorts_this_frag;
              break;
            }
          wid = the_ins.reloc[m].wid;
@@ -3668,9 +3703,9 @@ md_assemble (str)
                   the_ins.reloc[m].pcrel,
                   NO_RELOC);
        }
-      /* know(the_ins.fragb[n].fadd); */
-      (void) frag_var (rs_machine_dependent, 10, 0, (relax_substateT) (the_ins.fragb[n].fragty),
-                   the_ins.fragb[n].fadd, the_ins.fragb[n].foff, to_beg_P);
+      (void) frag_var (rs_machine_dependent, 10, 0,
+                      (relax_substateT) (the_ins.fragb[n].fragty),
+                      the_ins.fragb[n].fadd, the_ins.fragb[n].foff, to_beg_P);
     }
   n = (the_ins.numo - the_ins.fragb[n - 1].fragoff);
   shorts_this_frag = 0;
@@ -3696,7 +3731,7 @@ md_assemble (str)
       wid = (wid == 'b') ? 1 : (wid == 'w') ? 2 : (wid == 'l') ? 4 : 4000;
 
       fix_new (frag_now,
-              (the_ins.reloc[m].n + toP - frag_now->fr_literal) - /* the_ins.numo */ shorts_this_frag * 2,
+              (the_ins.reloc[m].n + toP - frag_now->fr_literal) - shorts_this_frag * 2,
               wid,
               the_ins.reloc[m].add,
               the_ins.reloc[m].sub,
@@ -3733,7 +3768,7 @@ md_begin ()
      my lord ghod hath spoken, so we do it this way.  Excuse the ugly var
      names.  */
 
-  register const struct m68k_opcode *ins;
+  register CONST struct m68k_opcode *ins;
   register struct m68k_incant *hack, *slak;
   register char *retval = 0;   /* empty string, or error msg text */
   register unsigned int i;
@@ -3894,7 +3929,7 @@ md_atof (type, litP, sizeP)
       md_number_to_chars (litP, (long) (*wordP++), sizeof (LITTLENUM_TYPE));
       litP += sizeof (LITTLENUM_TYPE);
     }
-  return "";                   /* Someone should teach Dean about null pointers */
+  return 0;
 }
 
 /* Turn an integer of n bytes (in val) into a stream of bytes appropriate
@@ -3930,11 +3965,14 @@ md_number_to_chars (buf, val, n)
     }
 }
 
-void
-md_apply_fix (fixP, val)
+static void
+md_apply_fix_2 (fixP, val)
      fixS *fixP;
      long val;
 {
+  unsigned long upper_limit;
+  long lower_limit;
+
 #ifdef IBM_COMPILER_SUX
   /* This is unnecessary but it convinces the native rs6000
      compiler to generate the code we want. */
@@ -3948,30 +3986,62 @@ md_apply_fix (fixP, val)
     {
     case 1:
       *buf++ = val;
+      upper_limit = 0x7f;
+      lower_limit = -0x80;
       break;
     case 2:
       *buf++ = (val >> 8);
       *buf++ = val;
+      upper_limit = 0x7fff;
+      lower_limit = -0x8000;
       break;
     case 4:
       *buf++ = (val >> 24);
       *buf++ = (val >> 16);
       *buf++ = (val >> 8);
       *buf++ = val;
+      upper_limit = 0x7fffffff;
+      lower_limit = -0x80000000;
       break;
     default:
       BAD_CASE (fixP->fx_size);
     }
+
+  /* For non-pc-relative values, it's conceivable we might get something
+     like "0xff" for a byte field.  So extend the upper part of the range
+     to accept such numbers.  We arbitrarily disallow "-0xff" or "0xff+0xff",
+     so that we can do any range checking at all.  */
+  if (!fixP->fx_pcrel)
+    upper_limit = upper_limit * 2 + 1;
+
+  if ((unsigned) val > upper_limit && (val > 0 || val < lower_limit))
+    as_bad ("value out of range");
 }
 
+#ifdef BFD_ASSEMBLER
+int
+md_apply_fix (fixP, valp)
+     fixS *fixP;
+     long *valp;
+{
+  md_apply_fix_2 (fixP, *valp);
+  return 1;
+}
+#else
+void md_apply_fix (fixP, val)
+     fixS *fixP;
+     long val;
+{
+  md_apply_fix_2 (fixP, val);
+}
+#endif
 
 /* *fragP has been relaxed to its final size, and now needs to have
    the bytes inside it modified to conform to the new size  There is UGLY
    MAGIC here. ..
    */
 void
-md_convert_frag (headers, fragP)
-     object_headers *headers;
+md_convert_frag_1 (fragP)
      register fragS *fragP;
 {
   long disp;
@@ -4023,7 +4093,7 @@ md_convert_frag (headers, fragP)
            {
              fragP->fr_opcode[0] = 0x4E;
              fragP->fr_opcode[1] = 0xB9;       /* JBSR with ABSL LONG offset */
-             subseg_change (SEG_TEXT, 0);
+             subseg_change (text_section, 0); /* @@ */
 
              fix_new (fragP,
                       fragP->fr_fix,
@@ -4041,7 +4111,7 @@ md_convert_frag (headers, fragP)
            {
              fragP->fr_opcode[0] = 0x4E;
              fragP->fr_opcode[1] = 0xF9;       /* JMP  with ABSL LONG offset */
-             subseg_change (SEG_TEXT, 0);
+             subseg_change (text_section, 0); /* @@ */
              fix_new (fragP, fragP->fr_fix, 4, fragP->fr_symbol, 0, fragP->fr_offset, 0,
                       NO_RELOC);
              fragP->fr_fix += 4;
@@ -4070,7 +4140,7 @@ md_convert_frag (headers, fragP)
       *buffer_address++ = 0x4e;        /* put in jmp long (0x4ef9) */
       *buffer_address++ = 0xf9;
       fragP->fr_fix += 2;      /* account for jmp instruction */
-      subseg_change (SEG_TEXT, 0);
+      subseg_change (text_section, 0);
       fix_new (fragP, fragP->fr_fix, 4, fragP->fr_symbol, 0,
               fragP->fr_offset, 0,
               NO_RELOC);
@@ -4089,10 +4159,9 @@ md_convert_frag (headers, fragP)
       *buffer_address++ = 0xf9;
 
       fragP->fr_fix += 6;      /* account for bra/jmp instructions */
-      subseg_change (SEG_TEXT, 0);
+      subseg_change (text_section, 0);
       fix_new (fragP, fragP->fr_fix, 4, fragP->fr_symbol, 0,
-              fragP->fr_offset, 0,
-              NO_RELOC);
+              fragP->fr_offset, 0, NO_RELOC);
       fragP->fr_fix += 4;
       ext = 0;
       break;
@@ -4111,49 +4180,64 @@ md_convert_frag (headers, fragP)
       /* The thing to do here is force it to ABSOLUTE LONG, since
        PCREL is really trying to shorten an ABSOLUTE address anyway */
       /* JF FOO This code has not been tested */
-      subseg_change (SEG_TEXT, 0);
-      fix_new (fragP, fragP->fr_fix, 4, fragP->fr_symbol, 0, fragP->fr_offset, 0, NO_RELOC);
+      subseg_change (text_section, 0);
+      fix_new (fragP, fragP->fr_fix, 4, fragP->fr_symbol, 0, fragP->fr_offset,
+              0, NO_RELOC);
       if ((fragP->fr_opcode[1] & 0x3F) != 0x3A)
        as_bad ("Internal error (long PC-relative operand) for insn 0x%04lx at 0x%lx",
                fragP->fr_opcode[0], fragP->fr_address);
       fragP->fr_opcode[1] &= ~0x3F;
       fragP->fr_opcode[1] |= 0x39;     /* Mode 7.1 */
       fragP->fr_fix += 4;
-      /* md_number_to_chars(buffer_address,
-          (long)(fragP->fr_symbol->sy_value + fragP->fr_offset),
-          4); */
       ext = 0;
       break;
     case TAB (PCLEA, SHORT):
-      subseg_change (SEG_TEXT, 0);
-      fix_new (fragP, (int) (fragP->fr_fix), 2, fragP->fr_symbol, (symbolS *) 0, fragP->fr_offset, 1,
-              NO_RELOC);
+      subseg_change (text_section, 0);
+      fix_new (fragP, (int) (fragP->fr_fix), 2, fragP->fr_symbol,
+              (symbolS *) 0, fragP->fr_offset, 1, NO_RELOC);
       fragP->fr_opcode[1] &= ~0x3F;
       fragP->fr_opcode[1] |= 0x3A;
       ext = 2;
       break;
     case TAB (PCLEA, LONG):
-      subseg_change (SEG_TEXT, 0);
-      fix_new (fragP, (int) (fragP->fr_fix) + 2, 4, fragP->fr_symbol, (symbolS *) 0, fragP->fr_offset + 2, 1,
-              NO_RELOC);
+      subseg_change (text_section, 0);
+      fix_new (fragP, (int) (fragP->fr_fix) + 2, 4, fragP->fr_symbol,
+              (symbolS *) 0, fragP->fr_offset + 2, 1, NO_RELOC);
       *buffer_address++ = 0x01;
       *buffer_address++ = 0x70;
       fragP->fr_fix += 2;
-      /* buffer_address+=2; */
       ext = 4;
       break;
-
-    }                          /* switch on subtype */
+    }
 
   if (ext)
     {
       md_number_to_chars (buffer_address, (long) disp, (int) ext);
       fragP->fr_fix += ext;
-      /*         H_SET_TEXT_SIZE(headers, H_GET_TEXT_SIZE(headers) + ext); */
-    }                          /* if extending */
+    }
+}
 
-  return;
-}                              /* md_convert_frag() */
+#ifndef BFD_ASSEMBLER
+
+void
+md_convert_frag (headers, fragP)
+     object_headers *headers;
+     fragS *fragP;
+{
+  md_convert_frag_1 (fragP);
+}
+
+#else
+
+void
+md_convert_frag (abfd, sec, fragP)
+     bfd *abfd;
+     asection sec;
+     fragS *fragP;
+{
+  md_convert_frag_1 (fragP);
+}
+#endif
 
 /* Force truly undefined symbols to their maximum size, and generally set up
    the frag list to be relaxed
@@ -4188,7 +4272,7 @@ md_estimate_size_before_relax (fragP, segment)
              {
                fragP->fr_opcode[0] = 0x4E;
                fragP->fr_opcode[1] = 0xB9;     /* JBSR with ABSL LONG offset */
-               subseg_change (SEG_TEXT, 0);
+               subseg_change (text_section, 0);
                fix_new (fragP, fragP->fr_fix, 4,
                         fragP->fr_symbol, 0, fragP->fr_offset, 0, NO_RELOC);
                fragP->fr_fix += 4;
@@ -4198,7 +4282,7 @@ md_estimate_size_before_relax (fragP, segment)
              {
                fragP->fr_opcode[0] = 0x4E;
                fragP->fr_opcode[1] = 0xF9;     /* JMP  with ABSL LONG offset */
-               subseg_change (SEG_TEXT, 0);
+               subseg_change (text_section, 0);
                fix_new (fragP, fragP->fr_fix, 4,
                         fragP->fr_symbol, 0, fragP->fr_offset, 0, NO_RELOC);
                fragP->fr_fix += 4;
@@ -4270,7 +4354,7 @@ md_estimate_size_before_relax (fragP, segment)
            buffer_address[0] = 0x4e;   /* put in jmp long (0x4ef9) */
            buffer_address[1] = 0xf8;
            fragP->fr_fix += 2; /* account for jmp instruction */
-           subseg_change (SEG_TEXT, 0);
+           subseg_change (text_section, 0);
            fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol, 0,
                     fragP->fr_offset, 0, NO_RELOC);
            fragP->fr_fix += 2;
@@ -4282,7 +4366,7 @@ md_estimate_size_before_relax (fragP, segment)
            buffer_address[0] = 0x4e;   /* put in jmp long (0x4ef9) */
            buffer_address[1] = 0xf9;
            fragP->fr_fix += 2; /* account for jmp instruction */
-           subseg_change (SEG_TEXT, 0);
+           subseg_change (text_section, 0);
            fix_new (fragP, fragP->fr_fix, 4, fragP->fr_symbol, 0,
                     fragP->fr_offset, 0, NO_RELOC);
            fragP->fr_fix += 4;
@@ -4313,7 +4397,7 @@ md_estimate_size_before_relax (fragP, segment)
            buffer_address[4] = 0x4e;   /* Put in Jump Word */
            buffer_address[5] = 0xf8;
            fragP->fr_fix += 6; /* account for bra/jmp instruction */
-           subseg_change (SEG_TEXT, 0);
+           subseg_change (text_section, 0);
            fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol, 0,
 
 
@@ -4327,7 +4411,7 @@ md_estimate_size_before_relax (fragP, segment)
            buffer_address[4] = 0x4e;   /* put in jmp long (0x4ef9) */
            buffer_address[5] = 0xf9;
            fragP->fr_fix += 6; /* account for bra/jmp instruction */
-           subseg_change (SEG_TEXT, 0);
+           subseg_change (text_section, 0);
            fix_new (fragP, fragP->fr_fix, 4, fragP->fr_symbol, 0,
                     fragP->fr_offset, 0, NO_RELOC);
            fragP->fr_fix += 4;
@@ -4406,6 +4490,7 @@ md_ri_to_chars (the_bytes, ri)
 
 #endif /* comment */
 
+#ifndef BFD_ASSEMBLER
 void
 tc_aout_fix_to_chars (where, fixP, segment_address_in_file)
      char *where;
@@ -4438,13 +4523,14 @@ tc_aout_fix_to_chars (where, fixP, segment_address_in_file)
              (((!S_IS_DEFINED (fixP->fx_addsy)) << 4) & 0x10));
 
   return;
-}                              /* tc_aout_fix_to_chars() */
+}
+#endif
 
 #endif /* OBJ_AOUT or OBJ_BOUT */
 
 #ifndef WORKING_DOT_WORD
-const int md_short_jump_size = 4;
-const int md_long_jump_size = 6;
+CONST int md_short_jump_size = 4;
+CONST int md_long_jump_size = 6;
 
 void
 md_create_short_jump (ptr, from_addr, to_addr, frag, to_symbol)
@@ -4524,6 +4610,7 @@ get_num (exp, ok)
 #else
   char *save_in;
   char c_save;
+  segT section;
 
   if (!exp)
     {
@@ -4532,7 +4619,7 @@ get_num (exp, ok)
     }
   if (!exp->e_beg || !exp->e_end)
     {
-      seg (exp) = SEG_ABSOLUTE;
+      seg (exp) = absolute_section;
       adds (exp) = 0;
       subs (exp) = 0;
       offs (exp) = (ok == 10) ? 1 : 0;
@@ -4573,19 +4660,19 @@ get_num (exp, ok)
   exp->e_end[1] = '\0';
   save_in = input_line_pointer;
   input_line_pointer = exp->e_beg;
-  switch (expression (&(exp->e_exp)))
+  section = expression (&exp->e_exp);
+  if (section == pass1_section)
     {
-    case SEG_PASS1:
-      seg (exp) = SEG_ABSOLUTE;
+      seg (exp) = absolute_section;
       adds (exp) = 0;
       subs (exp) = 0;
       offs (exp) = (ok == 10) ? 1 : 0;
       as_warn ("Unknown expression: '%s' defaulting to %d", exp->e_beg, offs (exp));
-      break;
-
-    case SEG_ABSENT:
+    }
+  else if (section == absent_section)
+    {
       /* Do the same thing the VAX asm does */
-      seg (exp) = SEG_ABSOLUTE;
+      seg (exp) = absolute_section;
       adds (exp) = 0;
       subs (exp) = 0;
       offs (exp) = 0;
@@ -4594,8 +4681,9 @@ get_num (exp, ok)
          as_warn ("expression out of range: defaulting to 1");
          offs (exp) = 1;
        }
-      break;
-    case SEG_ABSOLUTE:
+    }
+  else if (section == absolute_section)
+    {
       switch (ok)
        {
        case 10:
@@ -4640,8 +4728,9 @@ get_num (exp, ok)
        default:
          break;
        }
-      break;
-    case SEG_BIG:
+    }
+  else if (section == big_section)
+    {
       if (offs (exp) < 0       /* flonum */
          && (ok == 80          /* no bignums */
              || (ok > 10       /* small-int ranges including 0 ok */
@@ -4654,38 +4743,32 @@ get_num (exp, ok)
          LITTLENUM_TYPE words[6];
 
          gen_to_words (words, 2, 8L);  /* These numbers are magic! */
-         seg (exp) = SEG_ABSOLUTE;
+         seg (exp) = absolute_section;
          adds (exp) = 0;
          subs (exp) = 0;
          offs (exp) = words[1] | (words[0] << 16);
        }
       else if (ok != 0)
        {
-         seg (exp) = SEG_ABSOLUTE;
+         seg (exp) = absolute_section;
          adds (exp) = 0;
          subs (exp) = 0;
          offs (exp) = (ok == 10) ? 1 : 0;
          as_warn ("Can't deal with expression \"%s\": defaulting to %ld", exp->e_beg, offs (exp));
        }
-      break;
-    default:
-    case SEG_TEXT:
-    case SEG_DATA:
-    case SEG_BSS:
-    case SEG_UNKNOWN:
-    case SEG_DIFFERENCE:
+    }
+  else
+    {
       if (ok >= 10 && ok <= 70)
        {
-         seg (exp) = SEG_ABSOLUTE;
+         seg (exp) = absolute_section;
          adds (exp) = 0;
          subs (exp) = 0;
          offs (exp) = (ok == 10) ? 1 : 0;
          as_warn ("Can't deal with expression \"%s\": defaulting to %ld", exp->e_beg, offs (exp));
        }
-      break;
-
-
     }
+
   if (input_line_pointer != exp->e_end + 1)
     as_bad ("Ignoring junk after expression");
   exp->e_end[1] = c_save;
@@ -4706,7 +4789,7 @@ get_num (exp, ok)
     }
   return offs (exp);
 #endif
-}                              /* get_num() */
+}
 
 /* These are the back-ends for the various machine dependent pseudo-ops.  */
 void demand_empty_rest_of_line ();     /* Hate those extra verbose names */
@@ -4714,26 +4797,26 @@ void demand_empty_rest_of_line ();      /* Hate those extra verbose names */
 static void
 s_data1 ()
 {
-  subseg_new (SEG_DATA, 1);
+  subseg_new (data_section, 1);
   demand_empty_rest_of_line ();
-}                              /* s_data1() */
+}
 
 static void
 s_data2 ()
 {
-  subseg_new (SEG_DATA, 2);
+  subseg_new (data_section, 2);
   demand_empty_rest_of_line ();
-}                              /* s_data2() */
+}
 
 static void
 s_bss ()
 {
   /* We don't support putting frags in the BSS segment, we fake it
-          by marking in_bss, then looking at s_skip for clues */
+     by marking in_bss, then looking at s_skip for clues.  */
 
-  subseg_new (SEG_BSS, 0);
+  subseg_new (bss_section, 0);
   demand_empty_rest_of_line ();
-}                              /* s_bss() */
+}
 
 static void
 s_even ()
@@ -4746,13 +4829,13 @@ s_even ()
   if (!need_pass_2)            /* Never make frag if expect extra pass. */
     frag_align (temp, (int) temp_fill);
   demand_empty_rest_of_line ();
-}                              /* s_even() */
+}
 
 static void
 s_proc ()
 {
   demand_empty_rest_of_line ();
-}                              /* s_proc() */
+}
 
 /* s_space is defined in read.c .skip is simply an alias to it. */
 
@@ -5030,6 +5113,7 @@ md_pcrel_from (fixP)
   return (fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address);
 }
 
+#ifndef BFD_ASSEMBLER
 void
 tc_coff_symbol_emit_hook ()
 {
@@ -5050,7 +5134,7 @@ tc_coff_sizemachdep (frag)
     default:
       abort ();
     }
-
 }
+#endif
 
 /* end of tc-m68k.c */
index bc083748ccd11e9366b3099a3d076460c48c73a5..ede4e9041374a86ccff74357d88a45024423493b 100644 (file)
@@ -506,9 +506,12 @@ operand (expressionP)
       expressionP->X_seg = absolute_section;
       break;
 
+    case '+':
+      operand (expressionP);
+      break;
+
     case '~':
     case '-':
-    case '+':
       {
        /* unary operator: hope for SEG_ABSOLUTE */
        segT opseg = operand (expressionP);
@@ -677,8 +680,10 @@ clean_up_expression (expressionP)
       if (expressionP->X_subtract_symbol == expressionP->X_add_symbol
          || (expressionP->X_subtract_symbol
              && expressionP->X_add_symbol
-             && expressionP->X_subtract_symbol->sy_frag == expressionP->X_add_symbol->sy_frag
-             && S_GET_VALUE (expressionP->X_subtract_symbol) == S_GET_VALUE (expressionP->X_add_symbol)))
+             && (expressionP->X_subtract_symbol->sy_frag
+                 == expressionP->X_add_symbol->sy_frag)
+             && (S_GET_VALUE (expressionP->X_subtract_symbol)
+                 == S_GET_VALUE (expressionP->X_add_symbol))))
        {
          expressionP->X_subtract_symbol = NULL;
          expressionP->X_add_symbol = NULL;
@@ -721,16 +726,20 @@ expr_part (symbol_1_PP, symbol_2_P)
 {
   segT return_value;
 #ifndef MANY_SEGMENTS
-  assert ((*symbol_1_PP) == NULL \
-         || (S_GET_SEGMENT (*symbol_1_PP) == text_section) \
-         || (S_GET_SEGMENT (*symbol_1_PP) == data_section) \
-         || (S_GET_SEGMENT (*symbol_1_PP) == bss_section) \
-         || (!S_IS_DEFINED (*symbol_1_PP)));
-  assert (symbol_2_P == NULL \
-         || (S_GET_SEGMENT (symbol_2_P) == text_section) \
-         || (S_GET_SEGMENT (symbol_2_P) == data_section) \
-         || (S_GET_SEGMENT (symbol_2_P) == bss_section) \
+#ifndef OBJ_ECOFF
+  int test = ((*symbol_1_PP) == NULL
+             || (S_GET_SEGMENT (*symbol_1_PP) == text_section)
+             || (S_GET_SEGMENT (*symbol_1_PP) == data_section)
+             || (S_GET_SEGMENT (*symbol_1_PP) == bss_section)
+             || (!S_IS_DEFINED (*symbol_1_PP)));
+  assert (test);
+  test = (symbol_2_P == NULL
+         || (S_GET_SEGMENT (symbol_2_P) == text_section)
+         || (S_GET_SEGMENT (symbol_2_P) == data_section)
+         || (S_GET_SEGMENT (symbol_2_P) == bss_section)
          || (!S_IS_DEFINED (symbol_2_P)));
+  assert (test);
+#endif
 #endif
   if (*symbol_1_PP)
     {
@@ -785,12 +794,15 @@ expr_part (symbol_1_PP, symbol_2_P)
        }
     }
 #ifndef MANY_SEGMENTS
-  assert (return_value == absolute_section \
-         || return_value == text_section \
-         || return_value == data_section \
-         || return_value == bss_section \
-         || return_value == undefined_section \
+#ifndef OBJ_ECOFF
+  test = (return_value == absolute_section
+         || return_value == text_section
+         || return_value == data_section
+         || return_value == bss_section
+         || return_value == undefined_section
          || return_value == pass1_section);
+  assert (test);
+#endif
 #endif
   know ((*symbol_1_PP) == NULL
        || (S_GET_SEGMENT (*symbol_1_PP) == return_value));
@@ -836,6 +848,7 @@ typedef enum
 
 operatorT;
 
+#undef __
 #define __ O_illegal
 
 static const operatorT op_encoding[256] =
@@ -975,10 +988,11 @@ expr (rank, resultP)
              segT seg1;
              segT seg2;
 #ifndef MANY_SEGMENTS
-
+#ifndef OBJ_ECOFF
              know (resultP->X_seg == data_section || resultP->X_seg == text_section || resultP->X_seg == bss_section || resultP->X_seg == undefined_section || resultP->X_seg == diff_section || resultP->X_seg == absolute_section || resultP->X_seg == pass1_section || resultP->X_seg == reg_section);
 
              know (right.X_seg == data_section || right.X_seg == text_section || right.X_seg == bss_section || right.X_seg == undefined_section || right.X_seg == diff_section || right.X_seg == absolute_section || right.X_seg == pass1_section);
+#endif
 #endif
              clean_up_expression (&right);
              clean_up_expression (resultP);
@@ -1000,8 +1014,10 @@ expr (rank, resultP)
                  know (seg2 != absolute_section);
                  know (resultP->X_subtract_symbol);
 #ifndef MANY_SEGMENTS
+#ifndef OBJ_ECOFF
                  know (seg1 == text_section || seg1 == data_section || seg1 == bss_section);
                  know (seg2 == text_section || seg2 == data_section || seg2 == bss_section);
+#endif
 #endif
                  know (resultP->X_add_symbol);
                  know (resultP->X_subtract_symbol);
index 78061ef3411f300be9c70e256f9135c4fd79f37c..d50ed86147a3c64a49a8cecce1ea9bff5ceda0ec 100644 (file)
@@ -722,6 +722,8 @@ s_align_bytes (arg)
   if (temp && !need_pass_2)
     frag_align (temp, (int) temp_fill);
 
+  record_alignment (now_seg, temp);
+
   demand_empty_rest_of_line ();
 }                              /* s_align_bytes() */