Mention IA-64.
[deliverable/binutils-gdb.git] / gas / write.c
index e7370753379ffb277b48e1cb91a55fadedfe83dd..5a5c45b83aef144108d31dd4e8e857abf8f760fa 100644 (file)
@@ -1,5 +1,5 @@
 /* write.c - emit .o file
 /* write.c - emit .o file
-   Copyright (C) 1986, 87, 90, 91, 92, 93, 94, 95, 96, 1997
+   Copyright (C) 1986, 87, 90, 91, 92, 93, 94, 95, 96, 97, 98, 1999
    Free Software Foundation, Inc.
 
    This file is part of GAS, the GNU Assembler.
    Free Software Foundation, Inc.
 
    This file is part of GAS, the GNU Assembler.
@@ -112,6 +112,26 @@ static fixS *fix_new_internal PARAMS ((fragS *, int where, int size,
 static long fixup_segment PARAMS ((fixS * fixP, segT this_segment_type));
 #endif
 static relax_addressT relax_align PARAMS ((relax_addressT addr, int align));
 static long fixup_segment PARAMS ((fixS * fixP, segT this_segment_type));
 #endif
 static relax_addressT relax_align PARAMS ((relax_addressT addr, int align));
+#if defined (BFD_ASSEMBLER) || ! defined (BFD)
+static fragS *chain_frchains_together_1 PARAMS ((segT, struct frchain *));
+#endif
+#ifdef BFD_ASSEMBLER
+static void chain_frchains_together PARAMS ((bfd *, segT, PTR));
+static void cvt_frag_to_fill PARAMS ((segT, fragS *));
+static void relax_and_size_seg PARAMS ((bfd *, asection *, PTR));
+static void adjust_reloc_syms PARAMS ((bfd *, asection *, PTR));
+static void write_relocs PARAMS ((bfd *, asection *, PTR));
+static void write_contents PARAMS ((bfd *, asection *, PTR));
+static void set_symtab PARAMS ((void));
+#endif
+#if defined (BFD_ASSEMBLER) || (! defined (BFD) && ! defined (OBJ_AOUT))
+static void merge_data_into_text PARAMS ((void));
+#endif
+#if ! defined (BFD_ASSEMBLER) && ! defined (BFD)
+static void cvt_frag_to_fill PARAMS ((object_headers *, segT, fragS *));
+static void remove_subsegs PARAMS ((frchainS *, int, fragS **, fragS **));
+static void relax_and_size_all_segments PARAMS ((void));
+#endif
 
 /*
  *                     fix_new()
 
 /*
  *                     fix_new()
@@ -146,7 +166,7 @@ fix_new_internal (frag, where, size, add_symbol, sub_symbol, offset, pcrel,
   /* We've made fx_size a narrow field; check that it's wide enough.  */
   if (fixP->fx_size != size)
     {
   /* We've made fx_size a narrow field; check that it's wide enough.  */
   if (fixP->fx_size != size)
     {
-      as_bad ("field fx_size too small to hold %d", size);
+      as_bad (_("field fx_size too small to hold %d"), size);
       abort ();
     }
   fixP->fx_addsy = add_symbol;
       abort ();
     }
   fixP->fx_addsy = add_symbol;
@@ -166,6 +186,11 @@ fix_new_internal (frag, where, size, add_symbol, sub_symbol, offset, pcrel,
   fixP->fx_no_overflow = 0;
   fixP->fx_signed = 0;
 
   fixP->fx_no_overflow = 0;
   fixP->fx_signed = 0;
 
+#ifdef USING_CGEN
+  fixP->fx_cgen.insn = NULL;
+  fixP->fx_cgen.opinfo = 0;
+#endif
+
 #ifdef TC_FIX_TYPE
   TC_INIT_FIX_DATA(fixP);
 #endif
 #ifdef TC_FIX_TYPE
   TC_INIT_FIX_DATA(fixP);
 #endif
@@ -260,7 +285,6 @@ fix_new_exp (frag, where, size, exp, pcrel, r_type)
       /* This comes up when _GLOBAL_OFFSET_TABLE_+(.-L0) is read, if
         the difference expression cannot immediately be reduced.  */
       {
       /* This comes up when _GLOBAL_OFFSET_TABLE_+(.-L0) is read, if
         the difference expression cannot immediately be reduced.  */
       {
-       extern symbolS *make_expr_symbol ();
        symbolS *stmp = make_expr_symbol (exp);
        exp->X_op = O_symbol;
        exp->X_op_symbol = 0;
        symbolS *stmp = make_expr_symbol (exp);
        exp->X_op = O_symbol;
        exp->X_op_symbol = 0;
@@ -279,7 +303,7 @@ fix_new_exp (frag, where, size, exp, pcrel, r_type)
 #if defined(TC_RVA_RELOC)
       r_type = TC_RVA_RELOC;
 #else
 #if defined(TC_RVA_RELOC)
       r_type = TC_RVA_RELOC;
 #else
-      as_fatal("rva not supported");
+      as_fatal(_("rva not supported"));
 #endif
 #endif
       break;
 #endif
 #endif
       break;
@@ -344,7 +368,7 @@ record_alignment (seg, align)
   if (seg == absolute_section)
     return;
 #ifdef BFD_ASSEMBLER
   if (seg == absolute_section)
     return;
 #ifdef BFD_ASSEMBLER
-  if (align > bfd_get_section_alignment (stdoutput, seg))
+  if ((unsigned int) align > bfd_get_section_alignment (stdoutput, seg))
     bfd_set_section_alignment (stdoutput, seg, align);
 #else
   if (align > section_alignment[(int) seg])
     bfd_set_section_alignment (stdoutput, seg, align);
 #else
   if (align > section_alignment[(int) seg])
@@ -358,7 +382,7 @@ record_alignment (seg, align)
 
 static void
 renumber_sections (abfd, sec, countparg)
 
 static void
 renumber_sections (abfd, sec, countparg)
-     bfd *abfd;
+     bfd *abfd ATTRIBUTE_UNUSED;
      asection *sec;
      PTR countparg;
 {
      asection *sec;
      PTR countparg;
 {
@@ -409,9 +433,9 @@ chain_frchains_together_1 (section, frchp)
 
 static void
 chain_frchains_together (abfd, section, xxx)
 
 static void
 chain_frchains_together (abfd, section, xxx)
-     bfd *abfd;                        /* unused */
+     bfd *abfd ATTRIBUTE_UNUSED;
      segT section;
      segT section;
-     PTR xxx;                  /* unused */
+     PTR xxx ATTRIBUTE_UNUSED;
 {
   segment_info_type *info;
 
 {
   segment_info_type *info;
 
@@ -431,7 +455,7 @@ chain_frchains_together (abfd, section, xxx)
 
 #if !defined (BFD) && !defined (BFD_ASSEMBLER)
 
 
 #if !defined (BFD) && !defined (BFD_ASSEMBLER)
 
-void
+static void
 remove_subsegs (head, seg, root, last)
      frchainS *head;
      int seg;
 remove_subsegs (head, seg, root, last)
      frchainS *head;
      int seg;
@@ -474,8 +498,9 @@ cvt_frag_to_fill (headersP, sec, fragP)
                          - fragP->fr_fix) / fragP->fr_var;
       if (fragP->fr_offset < 0)
        {
                          - fragP->fr_fix) / fragP->fr_var;
       if (fragP->fr_offset < 0)
        {
-         as_bad ("attempt to .org/.space backwards? (%ld)",
-                 (long) fragP->fr_offset);
+         as_bad_where (fragP->fr_file, fragP->fr_line,
+                       _("attempt to .org/.space backwards? (%ld)"),
+                       (long) fragP->fr_offset);
        }
       fragP->fr_type = rs_fill;
       break;
        }
       fragP->fr_type = rs_fill;
       break;
@@ -483,6 +508,26 @@ cvt_frag_to_fill (headersP, sec, fragP)
     case rs_fill:
       break;
 
     case rs_fill:
       break;
 
+    case rs_leb128:
+      {
+       valueT value = S_GET_VALUE (fragP->fr_symbol);
+       int size;
+
+       size = output_leb128 (fragP->fr_literal + fragP->fr_fix, value,
+                             fragP->fr_subtype);
+
+       fragP->fr_fix += size;
+       fragP->fr_type = rs_fill;
+       fragP->fr_var = 0;
+       fragP->fr_offset = 0;
+       fragP->fr_symbol = NULL;
+      }
+      break;
+
+    case rs_cfa:
+      eh_frame_convert_frag (fragP);
+      break;
+
     case rs_machine_dependent:
 #ifdef BFD_ASSEMBLER
       md_convert_frag (stdoutput, sec, fragP);
     case rs_machine_dependent:
 #ifdef BFD_ASSEMBLER
       md_convert_frag (stdoutput, sec, fragP);
@@ -490,7 +535,9 @@ cvt_frag_to_fill (headersP, sec, fragP)
       md_convert_frag (headersP, sec, fragP);
 #endif
 
       md_convert_frag (headersP, sec, fragP);
 #endif
 
-      assert (fragP->fr_next == NULL || (fragP->fr_next->fr_address - fragP->fr_address == fragP->fr_fix));
+      assert (fragP->fr_next == NULL
+             || ((offsetT) (fragP->fr_next->fr_address - fragP->fr_address)
+                 == fragP->fr_fix));
 
       /*
        * After md_convert_frag, we make the frag into a ".space 0".
 
       /*
        * After md_convert_frag, we make the frag into a ".space 0".
@@ -532,7 +579,7 @@ static void
 relax_and_size_seg (abfd, sec, xxx)
      bfd *abfd;
      asection *sec;
 relax_and_size_seg (abfd, sec, xxx)
      bfd *abfd;
      asection *sec;
-     PTR xxx;
+     PTR xxx ATTRIBUTE_UNUSED;
 {
   flagword flags;
   fragS *fragp;
 {
   flagword flags;
   fragS *fragp;
@@ -598,7 +645,7 @@ relax_and_size_seg (abfd, sec, xxx)
 #ifdef DEBUG2
 static void
 dump_section_relocs (abfd, sec, stream_)
 #ifdef DEBUG2
 static void
 dump_section_relocs (abfd, sec, stream_)
-     bfd *abfd;
+     bfd *abfd ATTRIBUTE_UNUSED;
      asection *sec;
      char *stream_;
 {
      asection *sec;
      char *stream_;
 {
@@ -613,22 +660,16 @@ dump_section_relocs (abfd, sec, stream_)
   while (fixp)
     {
       symbolS *s = fixp->fx_addsy;
   while (fixp)
     {
       symbolS *s = fixp->fx_addsy;
-      if (s)
+
+      fprintf (stream, "  %08lx: type %d ", (unsigned long) fixp,
+              (int) fixp->fx_r_type);
+      if (s == NULL)
+       fprintf (stream, "no sym\n");
+      else
        {
        {
-         fprintf (stream, "  %08x: %s(%s", fixp, S_GET_NAME (s),
-                  s->bsym->section->name);
-         if (s->bsym->flags & BSF_SECTION_SYM)
-           {
-             fprintf (stream, " section sym");
-             if (S_GET_VALUE (s))
-               fprintf (stream, "+%x", S_GET_VALUE (s));
-           }
-         else
-           fprintf (stream, "+%x", S_GET_VALUE (s));
-         fprintf (stream, ")+%x\n", fixp->fx_offset);
+         print_symbol_value_1 (stream, s);
+         fprintf (stream, "\n");
        }
        }
-      else
-       fprintf (stream, "  %08x: type %d no sym\n", fixp, fixp->fx_r_type);
       fixp = fixp->fx_next;
     }
 }
       fixp = fixp->fx_next;
     }
 }
@@ -642,9 +683,9 @@ dump_section_relocs (abfd, sec, stream_)
 
 static void
 adjust_reloc_syms (abfd, sec, xxx)
 
 static void
 adjust_reloc_syms (abfd, sec, xxx)
-     bfd *abfd;
+     bfd *abfd ATTRIBUTE_UNUSED;
      asection *sec;
      asection *sec;
-     PTR xxx;
+     PTR xxx ATTRIBUTE_UNUSED;
 {
   segment_info_type *seginfo = seg_info (sec);
   fixS *fixp;
 {
   segment_info_type *seginfo = seg_info (sec);
   fixS *fixp;
@@ -662,8 +703,6 @@ adjust_reloc_syms (abfd, sec, xxx)
        symbolS *sym;
        asection *symsec;
 
        symbolS *sym;
        asection *symsec;
 
-      reduce_fixup:
-
 #ifdef DEBUG5
        fprintf (stderr, "\n\nadjusting fixup:\n");
        print_fixup (fixp);
 #ifdef DEBUG5
        fprintf (stderr, "\n\nadjusting fixup:\n");
        print_fixup (fixp);
@@ -675,39 +714,43 @@ adjust_reloc_syms (abfd, sec, xxx)
           point.  It is possible to see unresolved expression
           symbols, though, since they are not in the regular symbol
           table.  */
           point.  It is possible to see unresolved expression
           symbols, though, since they are not in the regular symbol
           table.  */
-       if (sym != NULL && ! sym->sy_resolved)
-         resolve_symbol_value (sym);
-       if (fixp->fx_subsy != NULL && ! fixp->fx_subsy->sy_resolved)
-         resolve_symbol_value (fixp->fx_subsy);
+       if (sym != NULL)
+         resolve_symbol_value (sym, 1);
+       
+       if (fixp->fx_subsy != NULL)
+         resolve_symbol_value (fixp->fx_subsy, 1);
 
        /* If this symbol is equated to an undefined symbol, convert
            the fixup to being against that symbol.  */
 
        /* If this symbol is equated to an undefined symbol, convert
            the fixup to being against that symbol.  */
-       if (sym->sy_value.X_op == O_symbol
+       if (sym != NULL && symbol_equated_p (sym)
            && (! S_IS_DEFINED (sym) || S_IS_COMMON (sym)))
          {
            && (! S_IS_DEFINED (sym) || S_IS_COMMON (sym)))
          {
-           fixp->fx_offset += sym->sy_value.X_add_number;
-           sym = sym->sy_value.X_add_symbol;
+           fixp->fx_offset += symbol_get_value_expression (sym)->X_add_number;
+           sym = symbol_get_value_expression (sym)->X_add_symbol;
            fixp->fx_addsy = sym;
          }
 
            fixp->fx_addsy = sym;
          }
 
-       symsec = S_GET_SEGMENT (sym);
-
-       if (sym != NULL && sym->sy_mri_common)
+       if (sym != NULL && symbol_mri_common_p (sym))
          {
            /* These symbols are handled specially in fixup_segment.  */
            goto done;
          }
 
          {
            /* These symbols are handled specially in fixup_segment.  */
            goto done;
          }
 
+       symsec = S_GET_SEGMENT (sym);
+
+       if (symsec == NULL)
+         abort ();
+       
        if (bfd_is_abs_section (symsec))
          {
            /* The fixup_segment routine will not use this symbol in a
                relocation unless TC_FORCE_RELOCATION returns 1.  */
            if (TC_FORCE_RELOCATION (fixp))
              {
        if (bfd_is_abs_section (symsec))
          {
            /* The fixup_segment routine will not use this symbol in a
                relocation unless TC_FORCE_RELOCATION returns 1.  */
            if (TC_FORCE_RELOCATION (fixp))
              {
-               fixp->fx_addsy->sy_used_in_reloc = 1;
+               symbol_mark_used_in_reloc (fixp->fx_addsy);
 #ifdef UNDEFINED_DIFFERENCE_OK
                if (fixp->fx_subsy != NULL)
 #ifdef UNDEFINED_DIFFERENCE_OK
                if (fixp->fx_subsy != NULL)
-                 fixp->fx_subsy->sy_used_in_reloc = 1;
+                 symbol_mark_used_in_reloc (fixp->fx_subsy);
 #endif
              }
            goto done;
 #endif
              }
            goto done;
@@ -721,22 +764,22 @@ adjust_reloc_syms (abfd, sec, xxx)
        if (bfd_is_und_section (symsec)
            || bfd_is_com_section (symsec))
          {
        if (bfd_is_und_section (symsec)
            || bfd_is_com_section (symsec))
          {
-           fixp->fx_addsy->sy_used_in_reloc = 1;
+           symbol_mark_used_in_reloc (fixp->fx_addsy);
 #ifdef UNDEFINED_DIFFERENCE_OK
            /* We have the difference of an undefined symbol and some
               other symbol.  Make sure to mark the other symbol as used
               in a relocation so that it will always be output.  */
            if (fixp->fx_subsy)
 #ifdef UNDEFINED_DIFFERENCE_OK
            /* We have the difference of an undefined symbol and some
               other symbol.  Make sure to mark the other symbol as used
               in a relocation so that it will always be output.  */
            if (fixp->fx_subsy)
-             fixp->fx_subsy->sy_used_in_reloc = 1;
+             symbol_mark_used_in_reloc (fixp->fx_subsy);
 #endif
            goto done;
          }
 
 #endif
            goto done;
          }
 
-       /* Don't try to reduce relocs which refer to .linkonce
-           sections.  It can lead to confusion when a debugging
-           section refers to a .linkonce section.  I hope this will
-           always be correct.  */
-       if (symsec != sec)
+       /* Don't try to reduce relocs which refer to non-local symbols
+           in .linkonce sections.  It can lead to confusion when a
+           debugging section refers to a .linkonce section.  I hope
+           this will always be correct.  */
+       if (symsec != sec && ! S_IS_LOCAL (sym))
          {
            boolean linkonce;
 
          {
            boolean linkonce;
 
@@ -757,10 +800,10 @@ adjust_reloc_syms (abfd, sec, xxx)
 
            if (linkonce)
              {
 
            if (linkonce)
              {
-               fixp->fx_addsy->sy_used_in_reloc = 1;
+               symbol_mark_used_in_reloc (fixp->fx_addsy);
 #ifdef UNDEFINED_DIFFERENCE_OK
                if (fixp->fx_subsy != NULL)
 #ifdef UNDEFINED_DIFFERENCE_OK
                if (fixp->fx_subsy != NULL)
-                 fixp->fx_subsy->sy_used_in_reloc = 1;
+                 symbol_mark_used_in_reloc (fixp->fx_subsy);
 #endif
                goto done;
              }
 #endif
                goto done;
              }
@@ -768,18 +811,30 @@ adjust_reloc_syms (abfd, sec, xxx)
 
        /* Since we're reducing to section symbols, don't attempt to reduce
           anything that's already using one.  */
 
        /* Since we're reducing to section symbols, don't attempt to reduce
           anything that's already using one.  */
-       if (sym->bsym->flags & BSF_SECTION_SYM)
+       if (symbol_section_p (sym))
+         {
+           symbol_mark_used_in_reloc (fixp->fx_addsy);
+           goto done;
+         }
+
+#ifdef BFD_ASSEMBLER
+       /* We can never adjust a reloc against a weak symbol.  If we
+           did, and the weak symbol was overridden by a real symbol
+           somewhere else, then our relocation would be pointing at
+           the wrong area of memory.  */
+       if (S_IS_WEAK (sym))
          {
          {
-           fixp->fx_addsy->sy_used_in_reloc = 1;
+           symbol_mark_used_in_reloc (fixp->fx_addsy);
            goto done;
          }
            goto done;
          }
+#endif
 
        /* Is there some other reason we can't adjust this one?  (E.g.,
           call/bal links in i960-bout symbols.)  */
 #ifdef obj_fix_adjustable
        if (! obj_fix_adjustable (fixp))
          {
 
        /* Is there some other reason we can't adjust this one?  (E.g.,
           call/bal links in i960-bout symbols.)  */
 #ifdef obj_fix_adjustable
        if (! obj_fix_adjustable (fixp))
          {
-           fixp->fx_addsy->sy_used_in_reloc = 1;
+           symbol_mark_used_in_reloc (fixp->fx_addsy);
            goto done;
          }
 #endif
            goto done;
          }
 #endif
@@ -790,7 +845,7 @@ adjust_reloc_syms (abfd, sec, xxx)
 #ifdef tc_fix_adjustable
        if (! tc_fix_adjustable (fixp))
          {
 #ifdef tc_fix_adjustable
        if (! tc_fix_adjustable (fixp))
          {
-           fixp->fx_addsy->sy_used_in_reloc = 1;
+           symbol_mark_used_in_reloc (fixp->fx_addsy);
            goto done;
          }
 #endif
            goto done;
          }
 #endif
@@ -804,7 +859,11 @@ adjust_reloc_syms (abfd, sec, xxx)
           the section when it calls resolve_symbol_value. */
        fixp->fx_offset += S_GET_VALUE (sym);
        fixp->fx_addsy = section_symbol (S_GET_SEGMENT (sym));
           the section when it calls resolve_symbol_value. */
        fixp->fx_offset += S_GET_VALUE (sym);
        fixp->fx_addsy = section_symbol (S_GET_SEGMENT (sym));
-       fixp->fx_addsy->sy_used_in_reloc = 1;
+       symbol_mark_used_in_reloc (fixp->fx_addsy);
+#ifdef DEBUG5
+       fprintf (stderr, "\nadjusted fixup:\n");
+       print_fixup (fixp);
+#endif
 
       done:
        ;
 
       done:
        ;
@@ -829,7 +888,7 @@ static void
 write_relocs (abfd, sec, xxx)
      bfd *abfd;
      asection *sec;
 write_relocs (abfd, sec, xxx)
      bfd *abfd;
      asection *sec;
-     PTR xxx;
+     PTR xxx ATTRIBUTE_UNUSED;
 {
   segment_info_type *seginfo = seg_info (sec);
   int i;
 {
   segment_info_type *seginfo = seg_info (sec);
   int i;
@@ -871,17 +930,17 @@ write_relocs (abfd, sec, xxx)
          symbol, then use generate the reloc against the latter symbol
          rather than the former.  */
       sym = fixp->fx_addsy;
          symbol, then use generate the reloc against the latter symbol
          rather than the former.  */
       sym = fixp->fx_addsy;
-      while (sym->sy_value.X_op == O_symbol
+      while (symbol_equated_p (sym)
             && (! S_IS_DEFINED (sym) || S_IS_COMMON (sym)))
        {
          symbolS *n;
 
          /* We must avoid looping, as that can occur with a badly
             written program.  */
             && (! S_IS_DEFINED (sym) || S_IS_COMMON (sym)))
        {
          symbolS *n;
 
          /* We must avoid looping, as that can occur with a badly
             written program.  */
-         n = sym->sy_value.X_add_symbol;
+         n = symbol_get_value_expression (sym)->X_add_symbol;
          if (n == sym)
            break;
          if (n == sym)
            break;
-         fixp->fx_offset += sym->sy_value.X_add_number;
+         fixp->fx_offset += symbol_get_value_expression (sym)->X_add_number;
          sym = n;
        }
       fixp->fx_addsy = sym;
          sym = n;
        }
       fixp->fx_addsy = sym;
@@ -909,18 +968,21 @@ write_relocs (abfd, sec, xxx)
        case bfd_reloc_ok:
          break;
        case bfd_reloc_overflow:
        case bfd_reloc_ok:
          break;
        case bfd_reloc_overflow:
-         as_bad_where (fixp->fx_file, fixp->fx_line, "relocation overflow");
+         as_bad_where (fixp->fx_file, fixp->fx_line, _("relocation overflow"));
+         break;
+       case bfd_reloc_outofrange:
+         as_bad_where (fixp->fx_file, fixp->fx_line, _("relocation out of range"));
          break;
        default:
          break;
        default:
-         as_fatal ("%s:%u: bad return from bfd_install_relocation",
-                   fixp->fx_file, fixp->fx_line);
+         as_fatal (_("%s:%u: bad return from bfd_install_relocation: %x"),
+                   fixp->fx_file, fixp->fx_line, s);
        }
       relocs[i++] = reloc;
     }
 #else
   n = n * MAX_RELOC_EXPANSION;
   /* Set up reloc information as well.  */
        }
       relocs[i++] = reloc;
     }
 #else
   n = n * MAX_RELOC_EXPANSION;
   /* Set up reloc information as well.  */
-  relocs = (arelent **) xmalloc (stdoutput, n * sizeof (arelent *));
+  relocs = (arelent **) xmalloc (n * sizeof (arelent *));
 
   i = 0;
   for (fixp = seginfo->fix_root; fixp != (fixS *) NULL; fixp = fixp->fx_next)
 
   i = 0;
   for (fixp = seginfo->fix_root; fixp != (fixS *) NULL; fixp = fixp->fx_next)
@@ -941,9 +1003,9 @@ write_relocs (abfd, sec, xxx)
          symbol, then use generate the reloc against the latter symbol
          rather than the former.  */
       sym = fixp->fx_addsy;
          symbol, then use generate the reloc against the latter symbol
          rather than the former.  */
       sym = fixp->fx_addsy;
-      while (sym->sy_value.X_op == O_symbol
+      while (symbol_equated_p (sym)
             && (! S_IS_DEFINED (sym) || S_IS_COMMON (sym)))
             && (! S_IS_DEFINED (sym) || S_IS_COMMON (sym)))
-       sym = sym->sy_value.X_add_symbol;
+       sym = symbol_get_value_expression (sym)->X_add_symbol;
       fixp->fx_addsy = sym;
 
       reloc = tc_gen_reloc (sec, fixp);
       fixp->fx_addsy = sym;
 
       reloc = tc_gen_reloc (sec, fixp);
@@ -957,7 +1019,7 @@ write_relocs (abfd, sec, xxx)
       if (fixp->fx_where + fixp->fx_size
          > fixp->fx_frag->fr_fix + fixp->fx_frag->fr_offset)
        as_bad_where (fixp->fx_file, fixp->fx_line,
       if (fixp->fx_where + fixp->fx_size
          > fixp->fx_frag->fr_fix + fixp->fx_frag->fr_offset)
        as_bad_where (fixp->fx_file, fixp->fx_line,
-                     "internal error: fixup not contained within frag");
+                     _("internal error: fixup not contained within frag"));
       for (j = 0; reloc[j]; j++)
         {
          s = bfd_install_relocation (stdoutput, reloc[j],
       for (j = 0; reloc[j]; j++)
         {
          s = bfd_install_relocation (stdoutput, reloc[j],
@@ -970,10 +1032,10 @@ write_relocs (abfd, sec, xxx)
              break;
            case bfd_reloc_overflow:
              as_bad_where (fixp->fx_file, fixp->fx_line,
              break;
            case bfd_reloc_overflow:
              as_bad_where (fixp->fx_file, fixp->fx_line,
-                           "relocation overflow");
+                           _("relocation overflow"));
              break;
            default:
              break;
            default:
-             as_fatal ("%s:%u: bad return from bfd_install_relocation",
+             as_fatal (_("%s:%u: bad return from bfd_install_relocation"),
                        fixp->fx_file, fixp->fx_line);
            }
         }
                        fixp->fx_file, fixp->fx_line);
            }
         }
@@ -1006,6 +1068,10 @@ write_relocs (abfd, sec, xxx)
                           (bfd_get_section_flags (abfd, sec)
                            & (flagword) ~SEC_RELOC));
 
                           (bfd_get_section_flags (abfd, sec)
                            & (flagword) ~SEC_RELOC));
 
+#ifdef SET_SECTION_RELOCS
+  SET_SECTION_RELOCS (sec, relocs, n);
+#endif
+
 #ifdef DEBUG3
   {
     int i;
 #ifdef DEBUG3
   {
     int i;
@@ -1025,9 +1091,9 @@ write_relocs (abfd, sec, xxx)
 
 static void
 write_contents (abfd, sec, xxx)
 
 static void
 write_contents (abfd, sec, xxx)
-     bfd *abfd;
+     bfd *abfd ATTRIBUTE_UNUSED;
      asection *sec;
      asection *sec;
-     PTR xxx;
+     PTR xxx ATTRIBUTE_UNUSED;
 {
   segment_info_type *seginfo = seg_info (sec);
   unsigned long offset = 0;
 {
   segment_info_type *seginfo = seg_info (sec);
   unsigned long offset = 0;
@@ -1056,7 +1122,7 @@ write_contents (abfd, sec, xxx)
          if (x == false)
            {
              bfd_perror (stdoutput->filename);
          if (x == false)
            {
              bfd_perror (stdoutput->filename);
-             as_perror ("FATAL: Can't write %s", stdoutput->filename);
+             as_perror (_("FATAL: Can't write %s"), stdoutput->filename);
              exit (EXIT_FAILURE);
            }
          offset += f->fr_fix;
              exit (EXIT_FAILURE);
            }
          offset += f->fr_fix;
@@ -1080,7 +1146,7 @@ write_contents (abfd, sec, xxx)
                  if (x == false)
                    {
                      bfd_perror (stdoutput->filename);
                  if (x == false)
                    {
                      bfd_perror (stdoutput->filename);
-                     as_perror ("FATAL: Can't write %s", stdoutput->filename);
+                     as_perror (_("FATAL: Can't write %s"), stdoutput->filename);
                      exit (EXIT_FAILURE);
                    }
                  offset += fill_size;
                      exit (EXIT_FAILURE);
                    }
                  offset += fill_size;
@@ -1111,7 +1177,7 @@ write_contents (abfd, sec, xxx)
                                                buf, (file_ptr) offset,
                                                (bfd_size_type) n_per_buf * fill_size);
                  if (x != true)
                                                buf, (file_ptr) offset,
                                                (bfd_size_type) n_per_buf * fill_size);
                  if (x != true)
-                   as_fatal ("Cannot write to output file.");
+                   as_fatal (_("Cannot write to output file."));
                  offset += n_per_buf * fill_size;
                }
            }
                  offset += n_per_buf * fill_size;
                }
            }
@@ -1270,8 +1336,8 @@ set_symtab ()
       symp = symbol_rootP;
       for (i = 0; i < nsyms; i++, symp = symbol_next (symp))
        {
       symp = symbol_rootP;
       for (i = 0; i < nsyms; i++, symp = symbol_next (symp))
        {
-         asympp[i] = symp->bsym;
-         symp->written = 1;
+         asympp[i] = symbol_get_bfdsym (symp);
+         symbol_mark_written (symp);
        }
     }
   else
        }
     }
   else
@@ -1282,10 +1348,53 @@ set_symtab ()
 }
 #endif
 
 }
 #endif
 
+/* Finish the subsegments.  After every sub-segment, we fake an
+   ".align ...".  This conforms to BSD4.2 brane-damage.  We then fake
+   ".fill 0" because that is the kind of frag that requires least
+   thought.  ".align" frags like to have a following frag since that
+   makes calculating their intended length trivial.  */
+
+#ifndef SUB_SEGMENT_ALIGN
+#ifdef BFD_ASSEMBLER
+#define SUB_SEGMENT_ALIGN(SEG) (0)
+#else
+#define SUB_SEGMENT_ALIGN(SEG) (2)
+#endif
+#endif
+
+void
+subsegs_finish ()
+{
+  struct frchain *frchainP;
+
+  for (frchainP = frchain_root; frchainP; frchainP = frchainP->frch_next)
+    {
+      subseg_set (frchainP->frch_seg, frchainP->frch_subseg);
+
+      /* This now gets called even if we had errors.  In that case,
+         any alignment is meaningless, and, moreover, will look weird
+         if we are generating a listing.  */
+      frag_align (had_errors () ? 0 : SUB_SEGMENT_ALIGN (now_seg),
+                 subseg_text_p (now_seg) ? NOP_OPCODE : 0,
+                 0);
+
+      /* frag_align will have left a new frag.
+        Use this last frag for an empty ".fill".
+
+        For this segment ...
+        Create a last frag. Do not leave a "being filled in frag".  */
+
+      frag_wane (frag_now);
+      frag_now->fr_fix = 0;
+      know (frag_now->fr_next == NULL);
+    }
+}
+
+/* Write the object file.  */
+
 void
 write_object_file ()
 {
 void
 write_object_file ()
 {
-  struct frchain *frchainP;    /* Track along all frchains. */
 #if ! defined (BFD_ASSEMBLER) || ! defined (WORKING_DOT_WORD)
   fragS *fragP;                        /* Track along all frags. */
 #endif
 #if ! defined (BFD_ASSEMBLER) || ! defined (WORKING_DOT_WORD)
   fragS *fragP;                        /* Track along all frags. */
 #endif
@@ -1300,14 +1409,14 @@ write_object_file ()
     if (flag_always_generate_output)
       {
        if (n_warns || n_errs)
     if (flag_always_generate_output)
       {
        if (n_warns || n_errs)
-         as_warn ("%d error%s, %d warning%s, generating bad object file.\n",
+         as_warn (_("%d error%s, %d warning%s, generating bad object file.\n"),
                   n_errs, n_errs == 1 ? "" : "s",
                   n_warns, n_warns == 1 ? "" : "s");
       }
     else
       {
        if (n_errs)
                   n_errs, n_errs == 1 ? "" : "s",
                   n_warns, n_warns == 1 ? "" : "s");
       }
     else
       {
        if (n_errs)
-         as_fatal ("%d error%s, %d warning%s, no object file generated.\n",
+         as_fatal (_("%d error%s, %d warning%s, no object file generated.\n"),
                    n_errs, n_errs == 1 ? "" : "s",
                    n_warns, n_warns == 1 ? "" : "s");
       }
                    n_errs, n_errs == 1 ? "" : "s",
                    n_warns, n_warns == 1 ? "" : "s");
       }
@@ -1320,34 +1429,6 @@ write_object_file ()
   vms_check_for_main ();
 #endif /* OBJ_VMS */
 
   vms_check_for_main ();
 #endif /* OBJ_VMS */
 
-  /* After every sub-segment, we fake an ".align ...". This conforms to
-     BSD4.2 brane-damage. We then fake ".fill 0" because that is the kind of
-     frag that requires least thought. ".align" frags like to have a
-     following frag since that makes calculating their intended length
-     trivial.
-
-     @@ Is this really necessary??  */
-#ifndef SUB_SEGMENT_ALIGN
-#ifdef BFD_ASSEMBLER
-#define SUB_SEGMENT_ALIGN(SEG) (0)
-#else
-#define SUB_SEGMENT_ALIGN(SEG) (2)
-#endif
-#endif
-  for (frchainP = frchain_root; frchainP; frchainP = frchainP->frch_next)
-    {
-      subseg_set (frchainP->frch_seg, frchainP->frch_subseg);
-      frag_align (SUB_SEGMENT_ALIGN (now_seg), NOP_OPCODE, 0);
-      /* frag_align will have left a new frag.
-        Use this last frag for an empty ".fill".
-
-        For this segment ...
-        Create a last frag. Do not leave a "being filled in frag".  */
-      frag_wane (frag_now);
-      frag_now->fr_fix = 0;
-      know (frag_now->fr_next == NULL);
-    }
-
   /* From now on, we don't care about sub-segments.  Build one frag chain
      for each segment. Linked thru fr_next.  */
 
   /* From now on, we don't care about sub-segments.  Build one frag chain
      for each segment. Linked thru fr_next.  */
 
@@ -1441,6 +1522,13 @@ write_object_file ()
 
   for (fragP = text_frag_root; fragP; fragP = fragP->fr_next)
     {
 
   for (fragP = text_frag_root; fragP; fragP = fragP->fr_next)
     {
+      /* At this point we have linked all the frags into a single
+         chain.  However, cvt_frag_to_fill may call md_convert_frag
+         which may call fix_new.  We need to ensure that fix_new adds
+         the fixup to the right section.  */
+      if (fragP == data_frag_root)
+       subseg_change (SEG_DATA, 0);
+
       cvt_frag_to_fill (&headers, SEG_TEXT, fragP);
 
       /* Some assert macros don't work with # directives mixed in.  */
       cvt_frag_to_fill (&headers, SEG_TEXT, fragP);
 
       /* Some assert macros don't work with # directives mixed in.  */
@@ -1467,6 +1555,7 @@ write_object_file ()
        {
          expressionS exp;
 
        {
          expressionS exp;
 
+         subseg_change (lie->seg, lie->subseg);
          exp.X_op = O_subtract;
          exp.X_add_symbol = lie->add;
          exp.X_op_symbol = lie->sub;
          exp.X_op = O_subtract;
          exp.X_add_symbol = lie->add;
          exp.X_op_symbol = lie->sub;
@@ -1511,6 +1600,7 @@ write_object_file ()
        addressT from_addr, to_addr;
        int n, m;
 
        addressT from_addr, to_addr;
        int n, m;
 
+       subseg_change (lie->seg, lie->subseg);
        fragP = lie->dispfrag;
 
        /* Find out how many broken_words go here.  */
        fragP = lie->dispfrag;
 
        /* Find out how many broken_words go here.  */
@@ -1537,7 +1627,10 @@ write_object_file ()
            /* This is the offset from ??? to table_ptr+0 */
            to_addr = table_addr - S_GET_VALUE (lie->sub);
 #ifdef BFD_ASSEMBLER
            /* This is the offset from ??? to table_ptr+0 */
            to_addr = table_addr - S_GET_VALUE (lie->sub);
 #ifdef BFD_ASSEMBLER
-           to_addr -= lie->sub->sy_frag->fr_address;
+           to_addr -= symbol_get_frag (lie->sub)->fr_address;
+#endif
+#ifdef TC_CHECK_ADJUSTED_BROKEN_DOT_WORD
+           TC_CHECK_ADJUSTED_BROKEN_DOT_WORD (to_addr, lie);
 #endif
            md_number_to_chars (lie->word_goes_here, to_addr, 2);
            for (untruth = lie->next_broken_word; untruth && untruth->dispfrag == fragP; untruth = untruth->next_broken_word)
 #endif
            md_number_to_chars (lie->word_goes_here, to_addr, 2);
            for (untruth = lie->next_broken_word; untruth && untruth->dispfrag == fragP; untruth = untruth->next_broken_word)
@@ -1551,7 +1644,7 @@ write_object_file ()
            from_addr = table_addr;
            to_addr = S_GET_VALUE (lie->add) + lie->addnum;
 #ifdef BFD_ASSEMBLER
            from_addr = table_addr;
            to_addr = S_GET_VALUE (lie->add) + lie->addnum;
 #ifdef BFD_ASSEMBLER
-           to_addr += lie->add->sy_frag->fr_address;
+           to_addr += symbol_get_frag (lie->add)->fr_address;
 #endif
            md_create_long_jump (table_ptr, from_addr, to_addr, lie->dispfrag, lie->add);
            table_ptr += md_long_jump_size;
 #endif
            md_create_long_jump (table_ptr, from_addr, to_addr, lie->dispfrag, lie->add);
            table_ptr += md_long_jump_size;
@@ -1684,9 +1777,9 @@ write_object_file ()
       symbolS *symp;
 
       for (symp = symbol_rootP; symp; symp = symbol_next (symp))
       symbolS *symp;
 
       for (symp = symbol_rootP; symp; symp = symbol_next (symp))
-       if (!symp->sy_resolved)
-         resolve_symbol_value (symp);
+       resolve_symbol_value (symp, 1);
     }
     }
+  resolve_local_symbol_values ();
 
   PROGRESS (1);
 
 
   PROGRESS (1);
 
@@ -1709,10 +1802,10 @@ write_object_file ()
          int punt = 0;
          const char *name;
 
          int punt = 0;
          const char *name;
 
-         if (symp->sy_mri_common)
+         if (symbol_mri_common_p (symp))
            {
              if (S_IS_EXTERNAL (symp))
            {
              if (S_IS_EXTERNAL (symp))
-               as_bad ("%s: global symbols not supported in common sections",
+               as_bad (_("%s: global symbols not supported in common sections"),
                        S_GET_NAME (symp));
              symbol_remove (symp, &symbol_rootP, &symbol_lastP);
              continue;
                        S_GET_NAME (symp));
              symbol_remove (symp, &symbol_rootP, &symbol_lastP);
              continue;
@@ -1725,29 +1818,17 @@ write_object_file ()
              /* They only differ if `name' is a fb or dollar local
                 label name.  */
              if (name2 != name && ! S_IS_DEFINED (symp))
              /* They only differ if `name' is a fb or dollar local
                 label name.  */
              if (name2 != name && ! S_IS_DEFINED (symp))
-               as_bad ("local label %s is not defined", name2);
+               as_bad (_("local label %s is not defined"), name2);
            }
 
          /* Do it again, because adjust_reloc_syms might introduce
             more symbols.  They'll probably only be section symbols,
             but they'll still need to have the values computed.  */
            }
 
          /* Do it again, because adjust_reloc_syms might introduce
             more symbols.  They'll probably only be section symbols,
             but they'll still need to have the values computed.  */
-         if (! symp->sy_resolved)
-           {
-             if (symp->sy_value.X_op == O_constant)
-               {
-                 /* This is the normal case; skip the call.  */
-                 S_SET_VALUE (symp,
-                              (S_GET_VALUE (symp)
-                               + symp->sy_frag->fr_address));
-                 symp->sy_resolved = 1;
-               }
-             else
-               resolve_symbol_value (symp);
-           }
+         resolve_symbol_value (symp, 1);
 
          /* Skip symbols which were equated to undefined or common
              symbols.  */
 
          /* Skip symbols which were equated to undefined or common
              symbols.  */
-         if (symp->sy_value.X_op == O_symbol
+         if (symbol_equated_p (symp)
              && (! S_IS_DEFINED (symp) || S_IS_COMMON (symp)))
            {
              symbol_remove (symp, &symbol_rootP, &symbol_lastP);
              && (! S_IS_DEFINED (symp) || S_IS_COMMON (symp)))
            {
              symbol_remove (symp, &symbol_rootP, &symbol_lastP);
@@ -1763,15 +1844,15 @@ write_object_file ()
          printf ("symbol `%s'\n\t@%x: value=%d flags=%x seg=%s\n",
                  S_GET_NAME (symp), symp,
                  S_GET_VALUE (symp),
          printf ("symbol `%s'\n\t@%x: value=%d flags=%x seg=%s\n",
                  S_GET_NAME (symp), symp,
                  S_GET_VALUE (symp),
-                 symp->bsym->flags,
-                 segment_name (symp->bsym->section));
+                 symbol_get_bfdsym (symp)->flags,
+                 segment_name (S_GET_SEGMENT (symp)));
 #endif
 
 #ifdef obj_frob_symbol
          obj_frob_symbol (symp, punt);
 #endif
 #ifdef tc_frob_symbol
 #endif
 
 #ifdef obj_frob_symbol
          obj_frob_symbol (symp, punt);
 #endif
 #ifdef tc_frob_symbol
-         if (! punt || symp->sy_used_in_reloc)
+         if (! punt || symbol_used_in_reloc_p (symp))
            tc_frob_symbol (symp, punt);
 #endif
 
            tc_frob_symbol (symp, punt);
 #endif
 
@@ -1781,13 +1862,13 @@ write_object_file ()
             and symbols that the frob_symbol macros told us to punt,
             but we keep such symbols if they are used in relocs.  */
          if ((! EMIT_SECTION_SYMBOLS
             and symbols that the frob_symbol macros told us to punt,
             but we keep such symbols if they are used in relocs.  */
          if ((! EMIT_SECTION_SYMBOLS
-              && (symp->bsym->flags & BSF_SECTION_SYM) != 0)
+              && symbol_section_p (symp))
              /* Note that S_IS_EXTERN and S_IS_LOCAL are not always
                 opposites.  Sometimes the former checks flags and the
                 latter examines the name...  */
              || (!S_IS_EXTERN (symp)
                  && (S_IS_LOCAL (symp) || punt)
              /* Note that S_IS_EXTERN and S_IS_LOCAL are not always
                 opposites.  Sometimes the former checks flags and the
                 latter examines the name...  */
              || (!S_IS_EXTERN (symp)
                  && (S_IS_LOCAL (symp) || punt)
-                 && ! symp->sy_used_in_reloc))
+                 && ! symbol_used_in_reloc_p (symp)))
            {
              symbol_remove (symp, &symbol_rootP, &symbol_lastP);
              /* After symbol_remove, symbol_next(symp) still returns
            {
              symbol_remove (symp, &symbol_rootP, &symbol_lastP);
              /* After symbol_remove, symbol_next(symp) still returns
@@ -1798,16 +1879,16 @@ write_object_file ()
            }
 
          /* Make sure we really got a value for the symbol.  */
            }
 
          /* Make sure we really got a value for the symbol.  */
-         if (! symp->sy_resolved)
+         if (! symbol_resolved_p (symp))
            {
            {
-             as_bad ("can't resolve value for symbol \"%s\"",
+             as_bad (_("can't resolve value for symbol \"%s\""),
                      S_GET_NAME (symp));
                      S_GET_NAME (symp));
-             symp->sy_resolved = 1;
+             symbol_mark_resolved (symp);
            }
 
          /* Set the value into the BFD symbol.  Up til now the value
             has only been kept in the gas symbolS struct.  */
            }
 
          /* Set the value into the BFD symbol.  Up til now the value
             has only been kept in the gas symbolS struct.  */
-         symp->bsym->value = S_GET_VALUE (symp);
+         symbol_get_bfdsym (symp)->value = S_GET_VALUE (symp);
        }
     }
 
        }
     }
 
@@ -1866,11 +1947,13 @@ write_object_file ()
 
 #ifdef TC_GENERIC_RELAX_TABLE
 
 
 #ifdef TC_GENERIC_RELAX_TABLE
 
+static int is_dnrange PARAMS ((fragS *, fragS *));
+
 /* Subroutines of relax_segment.  */
 static int
 is_dnrange (f1, f2)
 /* Subroutines of relax_segment.  */
 static int
 is_dnrange (f1, f2)
-     struct frag *f1;
-     struct frag *f2;
+     fragS *f1;
+     fragS *f2;
 {
   for (; f1; f1 = f1->fr_next)
     if (f1->fr_next == f2)
 {
   for (; f1; f1 = f1->fr_next)
     if (f1->fr_next == f2)
@@ -1914,9 +1997,7 @@ relax_frag (fragP, stretch)
 #endif
       know (!(S_GET_SEGMENT (symbolP) == absolute_section)
            || symbolP->sy_frag == &zero_address_frag);
 #endif
       know (!(S_GET_SEGMENT (symbolP) == absolute_section)
            || symbolP->sy_frag == &zero_address_frag);
-      target +=
-       S_GET_VALUE (symbolP)
-         + symbolP->sy_frag->fr_address;
+      target +=        S_GET_VALUE (symbolP) + symbol_get_frag (symbolP)->fr_address;
 
       /* If frag has yet to be reached on this pass,
         assume it will move by STRETCH just as we did.
 
       /* If frag has yet to be reached on this pass,
         assume it will move by STRETCH just as we did.
@@ -1927,8 +2008,8 @@ relax_frag (fragP, stretch)
 
         There should be a faster way to do this.  */
 
 
         There should be a faster way to do this.  */
 
-      if (symbolP->sy_frag->fr_address >= was_address
-         && is_dnrange (fragP, symbolP->sy_frag))
+      if (symbol_get_frag (symbolP)->fr_address >= was_address
+         && is_dnrange (fragP, symbol_get_frag (symbolP)))
        {
          target += stretch;
        }
        {
          target += stretch;
        }
@@ -1941,7 +2022,7 @@ relax_frag (fragP, stretch)
 /*#else*/
   /* This machine doesn't want to use pcrel_adjust.
      In that case, pcrel_adjust should be zero.  */
 /*#else*/
   /* This machine doesn't want to use pcrel_adjust.
      In that case, pcrel_adjust should be zero.  */
-/*  assert (fragP->fr_pcrel_adjust == 0);*/
+/*  assert (fragP->fr_targ.ns32k.pcrel_adjust == 0);*/
 #endif
 #ifdef md_prepare_relax_scan /* formerly called M68K_AIM_KLUDGE */
   md_prepare_relax_scan (fragP, address, aim, this_state, this_type);
 #endif
 #ifdef md_prepare_relax_scan /* formerly called M68K_AIM_KLUDGE */
   md_prepare_relax_scan (fragP, address, aim, this_state, this_type);
@@ -2042,7 +2123,7 @@ relax_segment (segment_frag_root, segment)
 
            if (offset % fragP->fr_var != 0)
              {
 
            if (offset % fragP->fr_var != 0)
              {
-               as_bad ("alignment padding (%lu bytes) not a multiple of %ld",
+               as_bad (_("alignment padding (%lu bytes) not a multiple of %ld"),
                        (unsigned long) offset, (long) fragP->fr_var);
                offset -= (offset % fragP->fr_var);
              }
                        (unsigned long) offset, (long) fragP->fr_var);
                offset -= (offset % fragP->fr_var);
              }
@@ -2066,6 +2147,16 @@ relax_segment (segment_frag_root, segment)
          break;
 #endif
 
          break;
 #endif
 
+       case rs_leb128:
+         /* Initial guess is always 1; doing otherwise can result in 
+            stable solutions that are larger than the minimum.  */
+         address += fragP->fr_offset = 1;
+         break;
+
+       case rs_cfa:
+         address += eh_frame_estimate_size_before_relax (fragP);
+         break;
+
        default:
          BAD_CASE (fragP->fr_type);
          break;
        default:
          BAD_CASE (fragP->fr_type);
          break;
@@ -2127,10 +2218,10 @@ relax_segment (segment_frag_root, segment)
                      if (lie->added)
                        continue;
 
                      if (lie->added)
                        continue;
 
-                     offset = (lie->add->sy_frag->fr_address
+                     offset = (symbol_get_frag (lie->add)->fr_address
                                + S_GET_VALUE (lie->add)
                                + lie->addnum
                                + S_GET_VALUE (lie->add)
                                + lie->addnum
-                               - (lie->sub->sy_frag->fr_address
+                               - (symbol_get_frag (lie->sub)->fr_address
                                   + S_GET_VALUE (lie->sub)));
                      if (offset <= -32768 || offset >= 32767)
                        {
                                   + S_GET_VALUE (lie->sub)));
                      if (offset <= -32768 || offset >= 32767)
                        {
@@ -2138,7 +2229,7 @@ relax_segment (segment_frag_root, segment)
                            {
                              char buf[50];
                              sprint_value (buf, (addressT) lie->addnum);
                            {
                              char buf[50];
                              sprint_value (buf, (addressT) lie->addnum);
-                             as_warn (".word %s-%s+%s didn't fit",
+                             as_warn (_(".word %s-%s+%s didn't fit"),
                                       S_GET_NAME (lie->add),
                                       S_GET_NAME (lie->sub),
                                       buf);
                                       S_GET_NAME (lie->add),
                                       S_GET_NAME (lie->sub),
                                       buf);
@@ -2152,8 +2243,10 @@ relax_segment (segment_frag_root, segment)
                          for (untruth = lie->next_broken_word;
                               untruth && untruth->dispfrag == lie->dispfrag;
                               untruth = untruth->next_broken_word)
                          for (untruth = lie->next_broken_word;
                               untruth && untruth->dispfrag == lie->dispfrag;
                               untruth = untruth->next_broken_word)
-                           if ((untruth->add->sy_frag == lie->add->sy_frag)
-                               && S_GET_VALUE (untruth->add) == S_GET_VALUE (lie->add))
+                           if ((symbol_get_frag (untruth->add)
+                                == symbol_get_frag (lie->add))
+                               && (S_GET_VALUE (untruth->add)
+                                   == S_GET_VALUE (lie->add)))
                              {
                                untruth->added = 2;
                                untruth->use_jump = lie;
                              {
                                untruth->added = 2;
                                untruth->use_jump = lie;
@@ -2203,8 +2296,8 @@ relax_segment (segment_frag_root, segment)
                      know (!(S_GET_SEGMENT (symbolP) == SEG_ABSOLUTE)
                            || (symbolP->sy_frag == &zero_address_frag));
 #endif
                      know (!(S_GET_SEGMENT (symbolP) == SEG_ABSOLUTE)
                            || (symbolP->sy_frag == &zero_address_frag));
 #endif
-                     target += S_GET_VALUE (symbolP)
-                       + symbolP->sy_frag->fr_address;
+                     target += (S_GET_VALUE (symbolP)
+                                + symbol_get_frag (symbolP)->fr_address);
                    }           /* if we have a symbol */
 
                  know (fragP->fr_next);
                    }           /* if we have a symbol */
 
                  know (fragP->fr_next);
@@ -2215,8 +2308,16 @@ relax_segment (segment_frag_root, segment)
                      /* Growth may be negative, but variable part of frag
                         cannot have fewer than 0 chars.  That is, we can't
                         .org backwards. */
                      /* Growth may be negative, but variable part of frag
                         cannot have fewer than 0 chars.  That is, we can't
                         .org backwards. */
-                     as_bad ("attempt to .org backwards ignored");
-                     growth = 0;
+                     as_bad_where (fragP->fr_file, fragP->fr_line,
+                                   _("attempt to .org backwards ignored"));
+
+                     /* We've issued an error message.  Change the
+                         frag to avoid cascading errors.  */
+                     fragP->fr_type = rs_align;
+                     fragP->fr_subtype = 0;
+                     fragP->fr_offset = 0;
+                     fragP->fr_fix = after - address;
+                     growth = stretch;
                    }
 
                  growth -= stretch;    /* This is an absolute growth factor */
                    }
 
                  growth -= stretch;    /* This is an absolute growth factor */
@@ -2227,15 +2328,15 @@ relax_segment (segment_frag_root, segment)
                if (symbolP)
                  {
                    growth = S_GET_VALUE (symbolP);
                if (symbolP)
                  {
                    growth = S_GET_VALUE (symbolP);
-                   if (symbolP->sy_frag != &zero_address_frag
+                   if (symbol_get_frag (symbolP) != &zero_address_frag
                        || S_IS_COMMON (symbolP)
                        || ! S_IS_DEFINED (symbolP))
                      as_bad_where (fragP->fr_file, fragP->fr_line,
                        || S_IS_COMMON (symbolP)
                        || ! S_IS_DEFINED (symbolP))
                      as_bad_where (fragP->fr_file, fragP->fr_line,
-                                   ".space specifies non-absolute value");
+                                   _(".space specifies non-absolute value"));
                    fragP->fr_symbol = 0;
                    if (growth < 0)
                      {
                    fragP->fr_symbol = 0;
                    if (growth < 0)
                      {
-                       as_warn (".space or .fill with negative value, ignored");
+                       as_warn (_(".space or .fill with negative value, ignored"));
                        growth = 0;
                      }
                  }
                        growth = 0;
                      }
                  }
@@ -2255,6 +2356,22 @@ relax_segment (segment_frag_root, segment)
 #endif
                break;
 
 #endif
                break;
 
+             case rs_leb128:
+               {
+                 valueT value;
+                 int size;
+
+                 value = resolve_symbol_value (fragP->fr_symbol, 0);
+                 size = sizeof_leb128 (value, fragP->fr_subtype);
+                 growth = size - fragP->fr_offset;
+                 fragP->fr_offset = size;
+               }
+               break;
+
+             case rs_cfa:
+               growth = eh_frame_relax_frag (fragP);
+               break;
+
              default:
                BAD_CASE (fragP->fr_type);
                break;
              default:
                BAD_CASE (fragP->fr_type);
                break;
@@ -2329,11 +2446,13 @@ fixup_segment (fixP, this_segment_type)
 
   for (; fixP; fixP = fixP->fx_next)
     {
 
   for (; fixP; fixP = fixP->fx_next)
     {
+
 #ifdef DEBUG5
       fprintf (stderr, "\nprocessing fixup:\n");
       print_fixup (fixP);
 #endif
 
 #ifdef DEBUG5
       fprintf (stderr, "\nprocessing fixup:\n");
       print_fixup (fixP);
 #endif
 
+
       fragP = fixP->fx_frag;
       know (fragP);
       where = fixP->fx_where;
       fragP = fixP->fx_frag;
       know (fragP);
       where = fixP->fx_where;
@@ -2349,12 +2468,13 @@ fixup_segment (fixP, this_segment_type)
       plt = fixP->fx_plt;
 
       if (add_symbolP != NULL
       plt = fixP->fx_plt;
 
       if (add_symbolP != NULL
-         && add_symbolP->sy_mri_common)
+         && symbol_mri_common_p (add_symbolP))
        {
          know (add_symbolP->sy_value.X_op == O_symbol);
          add_number += S_GET_VALUE (add_symbolP);
          fixP->fx_offset = add_number;
        {
          know (add_symbolP->sy_value.X_op == O_symbol);
          add_number += S_GET_VALUE (add_symbolP);
          fixP->fx_offset = add_number;
-         add_symbolP = fixP->fx_addsy = add_symbolP->sy_value.X_add_symbol;
+         add_symbolP = fixP->fx_addsy =
+           symbol_get_value_expression (add_symbolP)->X_add_symbol;
        }
 
       if (add_symbolP)
        }
 
       if (add_symbolP)
@@ -2362,7 +2482,7 @@ fixup_segment (fixP, this_segment_type)
 
       if (sub_symbolP)
        {
 
       if (sub_symbolP)
        {
-         resolve_symbol_value (sub_symbolP);
+         resolve_symbol_value (sub_symbolP, 1);
          if (add_symbolP == NULL || add_symbol_segment == absolute_section)
            {
              if (add_symbolP != NULL)
          if (add_symbolP == NULL || add_symbol_segment == absolute_section)
            {
              if (add_symbolP != NULL)
@@ -2387,7 +2507,7 @@ fixup_segment (fixP, this_segment_type)
              else
              bad_sub_reloc:
                as_bad_where (fixP->fx_file, fixP->fx_line,
              else
              bad_sub_reloc:
                as_bad_where (fixP->fx_file, fixP->fx_line,
-                             "Negative of non-absolute symbol %s",
+                             _("Negative of non-absolute symbol %s"),
                              S_GET_NAME (sub_symbolP));
            }
          else if (S_GET_SEGMENT (sub_symbolP) == add_symbol_segment
                              S_GET_NAME (sub_symbolP));
            }
          else if (S_GET_SEGMENT (sub_symbolP) == add_symbol_segment
@@ -2401,7 +2521,7 @@ fixup_segment (fixP, this_segment_type)
                 as the target of a call instruction.  */
              if (fixP->fx_tcbit)
                as_bad_where (fixP->fx_file, fixP->fx_line,
                 as the target of a call instruction.  */
              if (fixP->fx_tcbit)
                as_bad_where (fixP->fx_file, fixP->fx_line,
-                             "callj to difference of 2 symbols");
+                             _("callj to difference of 2 symbols"));
 #endif /* TC_I960 */
              add_number += S_GET_VALUE (add_symbolP) -
                S_GET_VALUE (sub_symbolP);
 #endif /* TC_I960 */
              add_number += S_GET_VALUE (add_symbolP) -
                S_GET_VALUE (sub_symbolP);
@@ -2467,9 +2587,12 @@ fixup_segment (fixP, this_segment_type)
                  char buf[50];
                  sprint_value (buf, fragP->fr_address + where);
                  as_bad_where (fixP->fx_file, fixP->fx_line,
                  char buf[50];
                  sprint_value (buf, fragP->fr_address + where);
                  as_bad_where (fixP->fx_file, fixP->fx_line,
-                               "Can't emit reloc {- %s-seg symbol \"%s\"} @ file address %s.",
+                               _("Subtraction of two symbols in different sections \"%s\" {%s section} - \"%s\" {%s section} at file address %s."),
+                               S_GET_NAME (add_symbolP),
+                               segment_name (S_GET_SEGMENT (add_symbolP)),
+                               S_GET_NAME (sub_symbolP),
                                segment_name (S_GET_SEGMENT (sub_symbolP)),
                                segment_name (S_GET_SEGMENT (sub_symbolP)),
-                               S_GET_NAME (sub_symbolP), buf);
+                               buf);
                }
            }
        }
                }
            }
        }
@@ -2542,7 +2665,7 @@ fixup_segment (fixP, this_segment_type)
                       * relocation.
                       */
                      as_bad_where (fixP->fx_file, fixP->fx_line,
                       * relocation.
                       */
                      as_bad_where (fixP->fx_file, fixP->fx_line,
-                                   "can't use COBR format with external label");
+                                   _("can't use COBR format with external label"));
                      fixP->fx_addsy = NULL;
                      fixP->fx_done = 1;
                      continue;
                      fixP->fx_addsy = NULL;
                      fixP->fx_done = 1;
                      continue;
@@ -2560,15 +2683,15 @@ fixup_segment (fixP, this_segment_type)
              else
                {
                  seg_reloc_count++;
              else
                {
                  seg_reloc_count++;
-/* start-sanitize-v850 */
 #if !(defined (TC_V850) && defined (OBJ_ELF))
 #if !(defined (TC_V850) && defined (OBJ_ELF))
-/* end-sanitize-v850 */
 #if !(defined (TC_M68K) && defined (OBJ_ELF))
 #if !(defined (TC_M68K) && defined (OBJ_ELF))
-#if !defined (TC_I386) || !(defined (OBJ_ELF) || defined (OBJ_COFF))
+#if !(defined (TC_ARM)  && defined (OBJ_ELF))
+#if !(defined (TC_I960) && defined (OBJ_ELF))
+#if !defined (TC_I386) || !(defined (OBJ_ELF) || defined (OBJ_COFF)) || defined (TE_PE)
                  add_number += S_GET_VALUE (add_symbolP);
                  add_number += S_GET_VALUE (add_symbolP);
-/* start-sanitize-v850 */
 #endif
 #endif
-/* end-sanitize-v850 */
+#endif
+#endif
 #endif
 #endif
                }
 #endif
 #endif
                }
@@ -2585,33 +2708,42 @@ fixup_segment (fixP, this_segment_type)
 #else
              fixP->fx_addsy = section_symbol (absolute_section);
 #endif
 #else
              fixP->fx_addsy = section_symbol (absolute_section);
 #endif
-             fixP->fx_addsy->sy_used_in_reloc = 1;
+             symbol_mark_used_in_reloc (fixP->fx_addsy);
              ++seg_reloc_count;
            }
        }
 
              ++seg_reloc_count;
            }
        }
 
+      if (!fixP->fx_done)
+       {
+#ifdef MD_APPLY_FIX3
+         md_apply_fix3 (fixP, &add_number, this_segment_type);
+#else
+#ifdef BFD_ASSEMBLER
+         md_apply_fix (fixP, &add_number);
+#else
+         md_apply_fix (fixP, add_number);
+#endif
+#endif
+
+#ifndef TC_HANDLES_FX_DONE
+         /* If the tc-* files haven't been converted, assume it's handling
+            it the old way, where a null fx_addsy means that the fix has
+            been applied completely, and no further work is needed.  */
+         if (fixP->fx_addsy == 0 && fixP->fx_pcrel == 0)
+           fixP->fx_done = 1;
+#endif
+       }
+
       if (!fixP->fx_bit_fixP && !fixP->fx_no_overflow && size > 0)
        {
       if (!fixP->fx_bit_fixP && !fixP->fx_no_overflow && size > 0)
        {
-         if (size < sizeof (valueT))
+         if ((size_t) size < sizeof (valueT))
            {
            {
-             valueT mask, hibit;
+             valueT mask;
 
 
-             /* set all bits to one */
              mask = 0;
              mask = 0;
-             mask--;
-             /* Technically, combining these produces an undefined result
-                if size is sizeof (valueT), though I think these two
-                half-way operations should both be defined.  And the
-                compiler should be able to combine them if it's valid on
-                the host architecture.  */
-             mask <<= size * 4;
-             mask <<= size * 4;
-             hibit = (valueT) 1 << (size * 8 - 1);
-             if (((add_number & mask) != 0
-                  || (fixP->fx_signed
-                      && (add_number & hibit) != 0))
-                 && ((add_number & mask) != mask
-                     || (add_number & hibit) == 0))
+             mask--;           /* set all bits to one */
+             mask <<= size * 8 - (fixP->fx_signed ? 1 : 0);
+             if ((add_number & mask) != 0 && (add_number & mask) != mask)
                {
                  char buf[50], buf2[50];
                  sprint_value (buf, fragP->fr_address + where);
                {
                  char buf[50], buf2[50];
                  sprint_value (buf, fragP->fr_address + where);
@@ -2620,7 +2752,7 @@ fixup_segment (fixP, this_segment_type)
                  else
                    sprintf (buf2, "%ld", (long) add_number);
                  as_bad_where (fixP->fx_file, fixP->fx_line,
                  else
                    sprintf (buf2, "%ld", (long) add_number);
                  as_bad_where (fixP->fx_file, fixP->fx_line,
-                               "Value of %s too large for field of %d bytes at %s",
+                               _("Value of %s too large for field of %d bytes at %s"),
                                buf2, size, buf);
                } /* generic error checking */
            }
                                buf2, size, buf);
                } /* generic error checking */
            }
@@ -2632,34 +2764,15 @@ fixup_segment (fixP, this_segment_type)
              && size == 2
              && add_number > 0x7fff)
            as_bad_where (fixP->fx_file, fixP->fx_line,
              && size == 2
              && add_number > 0x7fff)
            as_bad_where (fixP->fx_file, fixP->fx_line,
-                         "Signed .word overflow; switch may be too large; %ld at 0x%lx",
+                         _("Signed .word overflow; switch may be too large; %ld at 0x%lx"),
                          (long) add_number,
                          (unsigned long) (fragP->fr_address + where));
 #endif
        }                       /* not a bit fix */
 
                          (long) add_number,
                          (unsigned long) (fragP->fr_address + where));
 #endif
        }                       /* not a bit fix */
 
-      if (!fixP->fx_done)
-       {
-#ifdef MD_APPLY_FIX3
-         md_apply_fix3 (fixP, &add_number, this_segment_type);
-#else
-#ifdef BFD_ASSEMBLER
-         md_apply_fix (fixP, &add_number);
-#else
-         md_apply_fix (fixP, add_number);
-#endif
-#endif
-
-#ifndef TC_HANDLES_FX_DONE
-         /* If the tc-* files haven't been converted, assume it's handling
-            it the old way, where a null fx_addsy means that the fix has
-            been applied completely, and no further work is needed.  */
-         if (fixP->fx_addsy == 0 && fixP->fx_pcrel == 0)
-           fixP->fx_done = 1;
-#endif
-       }
 #ifdef TC_VALIDATE_FIX
 #ifdef TC_VALIDATE_FIX
-    skip: ;
+    skip:  ATTRIBUTE_UNUSED_LABEL
+      ;
 #endif
 #ifdef DEBUG5
       fprintf (stderr, "result:\n");
 #endif
 #ifdef DEBUG5
       fprintf (stderr, "result:\n");
@@ -2679,7 +2792,7 @@ number_to_chars_bigendian (buf, val, n)
      valueT val;
      int n;
 {
      valueT val;
      int n;
 {
-  if (n > sizeof (val)|| n <= 0)
+  if ((size_t) n > sizeof (val) || n <= 0)
     abort ();
   while (n--)
     {
     abort ();
   while (n--)
     {
@@ -2694,7 +2807,7 @@ number_to_chars_littleendian (buf, val, n)
      valueT val;
      int n;
 {
      valueT val;
      int n;
 {
-  if (n > sizeof (val) || n <= 0)
+  if ((size_t) n > sizeof (val) || n <= 0)
     abort ();
   while (n--)
     {
     abort ();
   while (n--)
     {
@@ -2707,12 +2820,11 @@ void
 write_print_statistics (file)
      FILE *file;
 {
 write_print_statistics (file)
      FILE *file;
 {
-  fprintf (stderr, "fixups: %d\n", n_fixups);
+  fprintf (file, "fixups: %d\n", n_fixups);
 }
 
 /* for debugging */
 extern int indent_level;
 }
 
 /* for debugging */
 extern int indent_level;
-extern void print_symbol_value_1 ();
 
 void
 print_fixup (fixp)
 
 void
 print_fixup (fixp)
@@ -2760,6 +2872,9 @@ print_fixup (fixp)
       fprintf (stderr, ">");
     }
   fprintf (stderr, "\n");
       fprintf (stderr, ">");
     }
   fprintf (stderr, "\n");
+#ifdef TC_FIX_DATA_PRINT
+  TC_FIX_DATA_PRINT (stderr, fixp);
+#endif
 }
 
 /* end of write.c */
 }
 
 /* end of write.c */
This page took 0.041124 seconds and 4 git commands to generate.