Add new command line switch --no-construct-floats
[deliverable/binutils-gdb.git] / gas / config / tc-mips.c
index 9426519c676fb4007d1d4eb676f07474359c981f..1333d058a3a0aca3309529ba238a34cb26a7ef61 100644 (file)
@@ -121,9 +121,15 @@ mips_target_format ()
     case bfd_target_coff_flavour:
       return "pe-mips";
     case bfd_target_elf_flavour:
+#ifdef TE_TMIPS
+      /* This is traditional mips */
+      return (target_big_endian
+              ? "elf32-tradbigmips" : "elf32-tradlittlemips");
+#else
       return (target_big_endian
              ? (mips_64 ? "elf64-bigmips" : "elf32-bigmips")
              : (mips_64 ? "elf64-littlemips" : "elf32-littlemips"));
+#endif
     default:
       abort ();
       return NULL;
@@ -183,7 +189,7 @@ struct mips_set_options
    that we must set the isa and mips16 fields to -1 to indicate that
    they have not been initialized.  */
 
-static struct mips_set_options mips_opts = { -1, -1 };
+static struct mips_set_options mips_opts = { -1, -1, 0, 0, 0, 0, 0, 0 };
 
 /* These variables are filled in with the masks of registers used.
    The object format code reads them and puts them in the appropriate
@@ -307,6 +313,14 @@ static int mips_big_got;
    instructions.  */
 static int mips_trap;
 
+/* 1 if double width floating point constants should not be constructed
+   by a assembling two single width halves into two single width floating
+   point registers which just happen to alias the double width destination
+   register.  On some architectures this aliasing can be disabled by a bit
+   in the status register, and the settin gof this bit cannot be determined
+   automatically at assemble time.  */
+static int mips_disable_float_construction;
+
 /* Non-zero if any .set noreorder directives were used.  */
 
 static int mips_any_noreorder;
@@ -357,7 +371,7 @@ const char comment_chars[] = "#";
 const char line_comment_chars[] = "#";
 
 /* This array holds machine specific line separator characters. */
-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";
@@ -407,7 +421,7 @@ static struct mips_cl_insn prev_prev_insn;
 
 /* If we don't want information for prev_insn or prev_prev_insn, we
    point the insn_mo field at this dummy integer.  */
-static const struct mips_opcode dummy_opcode = { 0 };
+static const struct mips_opcode dummy_opcode = { NULL, NULL, 0, 0, 0, 0 };
 
 /* Non-zero if prev_insn is valid.  */
 static int prev_insn_valid;
@@ -756,7 +770,7 @@ static const pseudo_typeS mips_pseudo_table[] =
   {"stabn", s_mips_stab, 'n'},
   {"text", s_change_sec, 't'},
   {"word", s_cons, 2},
-  { 0 },
+  { NULL, NULL, 0 },
 };
 
 static const pseudo_typeS mips_nonecoff_pseudo_table[] = {
@@ -773,7 +787,7 @@ static const pseudo_typeS mips_nonecoff_pseudo_table[] = {
   {"loc", s_ignore, 0},
   {"mask", s_mips_mask, 'R'},
   {"verstamp", s_ignore, 0},
-  { 0 },
+  { NULL, NULL, 0 },
 };
 
 extern void pop_insert PARAMS ((const pseudo_typeS *));
@@ -2597,7 +2611,6 @@ macro_build (place, counter, ep, name, fmt, va_alist)
                  || r == BFD_RELOC_MIPS_GOT_LO16
                  || r == BFD_RELOC_MIPS_CALL_LO16
                  || (ep->X_op == O_subtract
-                     && now_seg == text_section
                      && r == BFD_RELOC_PCREL_LO16));
          continue;
 
@@ -2611,7 +2624,6 @@ macro_build (place, counter, ep, name, fmt, va_alist)
                              || r == BFD_RELOC_MIPS_GOT_HI16
                              || r == BFD_RELOC_MIPS_CALL_HI16))
                      || (ep->X_op == O_subtract
-                         && now_seg == text_section
                          && r == BFD_RELOC_PCREL_HI16_S)));
          if (ep->X_op == O_constant)
            {
@@ -2662,7 +2674,7 @@ macro_build (place, counter, ep, name, fmt, va_alist)
 static void
 mips16_macro_build (place, counter, ep, name, fmt, args)
      char *place;
-     int *counter;
+     int *counter ATTRIBUTE_UNUSED;
      expressionS *ep;
      const char *name;
      const char *fmt;
@@ -3445,7 +3457,7 @@ macro (ip)
   int tempreg;
   int mask;
   int icnt = 0;
-  int used_at;
+  int used_at = 0;
   expressionS expr1;
   const char *s;
   const char *s2;
@@ -4150,23 +4162,23 @@ macro (ip)
       /* When generating embedded PIC code, we permit expressions of
         the form
           la   $4,foo-bar
-        where bar is an address in the .text section.  These are used
+        where bar is an address in the current section.  These are used
         when getting the addresses of functions.  We don't permit
         X_add_number to be non-zero, because if the symbol is
         external the relaxing code needs to know that any addend is
         purely the offset to X_op_symbol.  */
       if (mips_pic == EMBEDDED_PIC
          && offset_expr.X_op == O_subtract
-         && now_seg == text_section
          && (symbol_constant_p (offset_expr.X_op_symbol)
-             ? S_GET_SEGMENT (offset_expr.X_op_symbol) == text_section
+             ? S_GET_SEGMENT (offset_expr.X_op_symbol) == now_seg
              : (symbol_equated_p (offset_expr.X_op_symbol)
                 && (S_GET_SEGMENT
                     (symbol_get_value_expression (offset_expr.X_op_symbol)
                      ->X_add_symbol)
-                    == text_section)))
+                    == now_seg)))
          && breg == 0
-         && offset_expr.X_add_number == 0)
+         && (offset_expr.X_add_number == 0
+             || OUTPUT_FLAVOR == bfd_target_elf_flavour))
        {
          macro_build ((char *) NULL, &icnt, &offset_expr, "lui", "t,u",
                       treg, (int) BFD_RELOC_PCREL_HI16_S);
@@ -6410,8 +6422,8 @@ macro2 (ip)
       macro_build ((char *) NULL, &icnt, NULL, s, "s,t", sreg, AT);
       break;
 
-    case M_TRUNCWD:
     case M_TRUNCWS:
+    case M_TRUNCWD:
       assert (mips_opts.isa == 1);
       sreg = (ip->insn_opcode >> 11) & 0x1f;   /* floating reg */
       dreg = (ip->insn_opcode >> 06) & 0x1f;   /* floating reg */
@@ -6999,7 +7011,7 @@ mips_ip (str, ip)
 {
   char *s;
   const char *args;
-  char c;
+  char c = 0;
   struct mips_opcode *insn;
   char *argsStart;
   unsigned int regno;
@@ -7085,7 +7097,7 @@ mips_ip (str, ip)
              continue;
            }
          else
-           {
+           {
              static char buf[100];
              sprintf (buf, 
                       _("opcode not supported on this processor: %d (MIPS%d)"),
@@ -7597,6 +7609,7 @@ mips_ip (str, ip)
                      imm_expr.X_add_number = bfd_getb32 (temp);
                  }
                else if (length > 4
+                        && ! mips_disable_float_construction
                         && ((temp[0] == 0 && temp[1] == 0)
                             || (temp[2] == 0 && temp[3] == 0))
                         && ((temp[4] == 0 && temp[5] == 0)
@@ -7666,11 +7679,15 @@ mips_ip (str, ip)
                      default: /* unused default case avoids warnings.  */
                      case 'L':
                        newname = RDATA_SECTION_NAME;
-                       if (USE_GLOBAL_POINTER_OPT && g_switch_value >= 8)
+                       if ((USE_GLOBAL_POINTER_OPT && g_switch_value >= 8)
+                           || mips_pic == EMBEDDED_PIC)
                          newname = ".lit8";
                        break;
                      case 'F':
-                       newname = RDATA_SECTION_NAME;
+                       if (mips_pic == EMBEDDED_PIC)
+                         newname = ".lit8";
+                       else
+                         newname = RDATA_SECTION_NAME;
                        break;
                      case 'l':
                        assert (!USE_GLOBAL_POINTER_OPT
@@ -7744,10 +7761,8 @@ mips_ip (str, ip)
                      if (insn + 1 < &mips_opcodes[NUMOPCODES] &&
                          !strcmp (insn->name, insn[1].name))
                        break;
-                     if (imm_expr.X_op != O_constant
-                         && imm_expr.X_op != O_big)
-                       insn_error = _("absolute expression required");
-                     else
+                     if (imm_expr.X_op == O_constant
+                         || imm_expr.X_op == O_big)
                        as_bad (_("16 bit expression not in range 0..65535"));
                    }
                }
@@ -7783,10 +7798,8 @@ mips_ip (str, ip)
                    {
                      if (more)
                        break;
-                     if (imm_expr.X_op != O_constant
-                         && imm_expr.X_op != O_big)
-                       insn_error = _("absolute expression required");
-                     else
+                     if (imm_expr.X_op == O_constant
+                         || imm_expr.X_op == O_big)
                        as_bad (_("16 bit expression not in range -32768..32767"));
                    }
                }
@@ -7813,9 +7826,8 @@ mips_ip (str, ip)
                      || offset_expr.X_add_number < -0x8000)
                  && (mips_pic != EMBEDDED_PIC
                      || offset_expr.X_op != O_subtract
-                     || now_seg != text_section
                      || (S_GET_SEGMENT (offset_expr.X_op_symbol)
-                         != text_section)))
+                         != now_seg)))
                break;
 
              if (c == 'h' || c == 'H')
@@ -8739,8 +8751,8 @@ my_getExpression (ep, str)
 }
 
 /* Turn a string in input_line_pointer into a floating point constant
-   of type type, and store the appropriate bytes in *litP.  The number
-   of LITTLENUMS emitted is stored in *sizeP .  An error message is
+   of type TYPE, and store the appropriate bytes in *LITP.  The number
+   of LITTLENUMS emitted is stored in *SIZEP.  An error message is
    returned, or NULL on OK.  */
 
 char *
@@ -8823,6 +8835,10 @@ struct option md_longopts[] = {
   {"mcpu", required_argument, NULL, OPTION_MCPU},
 #define OPTION_MEMBEDDED_PIC (OPTION_MD_BASE + 6)
   {"membedded-pic", no_argument, NULL, OPTION_MEMBEDDED_PIC},
+
+#define OPTION_CALL_SHARED (OPTION_MD_BASE + 7)
+#define OPTION_NON_SHARED (OPTION_MD_BASE + 8)
+
 #define OPTION_TRAP (OPTION_MD_BASE + 9)
   {"trap", no_argument, NULL, OPTION_TRAP},
   {"no-break", no_argument, NULL, OPTION_TRAP},
@@ -8845,16 +8861,21 @@ struct option md_longopts[] = {
   {"m4100", no_argument, NULL, OPTION_M4100},
 #define OPTION_NO_M4100 (OPTION_MD_BASE + 18)
   {"no-m4100", no_argument, NULL, OPTION_NO_M4100},
+
+#define OPTION_XGOT (OPTION_MD_BASE + 19)
+#define OPTION_32 (OPTION_MD_BASE + 20)
+#define OPTION_64 (OPTION_MD_BASE + 21)
+  
 #define OPTION_MIPS16 (OPTION_MD_BASE + 22)
   {"mips16", no_argument, NULL, OPTION_MIPS16},
 #define OPTION_NO_MIPS16 (OPTION_MD_BASE + 23)
   {"no-mips16", no_argument, NULL, OPTION_NO_MIPS16},
+
 #define OPTION_M3900 (OPTION_MD_BASE + 26)
   {"m3900", no_argument, NULL, OPTION_M3900},
 #define OPTION_NO_M3900 (OPTION_MD_BASE + 27)
   {"no-m3900", no_argument, NULL, OPTION_NO_M3900},
 
-
 #define OPTION_MABI (OPTION_MD_BASE + 38)
   {"mabi", required_argument, NULL, OPTION_MABI},
 
@@ -8863,11 +8884,6 @@ struct option md_longopts[] = {
 #define OPTION_NO_M7000_HILO_FIX (OPTION_MD_BASE + 40)
   {"no-fix-7000", no_argument, NULL, OPTION_NO_M7000_HILO_FIX},
 
-#define OPTION_CALL_SHARED (OPTION_MD_BASE + 7)
-#define OPTION_NON_SHARED (OPTION_MD_BASE + 8)
-#define OPTION_XGOT (OPTION_MD_BASE + 19)
-#define OPTION_32 (OPTION_MD_BASE + 20)
-#define OPTION_64 (OPTION_MD_BASE + 21)
 #ifdef OBJ_ELF
   {"KPIC", no_argument, NULL, OPTION_CALL_SHARED},
   {"xgot", no_argument, NULL, OPTION_XGOT},
@@ -8882,6 +8898,12 @@ struct option md_longopts[] = {
   {"mgp32", no_argument, NULL, OPTION_GP32},
   {"mgp64", no_argument, NULL, OPTION_GP64},
 
+#define OPTION_CONSTRUCT_FLOATS (OPTION_MD_BASE + 43)
+  {"construct-floats", no_argument, NULL, OPTION_CONSTRUCT_FLOATS},
+
+#define OPTION_NO_CONSTRUCT_FLOATS (OPTION_MD_BASE + 44)
+  {"no-construct-floats", no_argument, NULL, OPTION_NO_CONSTRUCT_FLOATS},
+
   {NULL, no_argument, NULL, 0}
 };
 size_t md_longopts_size = sizeof(md_longopts);
@@ -8893,6 +8915,14 @@ md_parse_option (c, arg)
 {
   switch (c)
     {
+    case OPTION_CONSTRUCT_FLOATS:
+      mips_disable_float_construction = 0;
+      break;
+      
+    case OPTION_NO_CONSTRUCT_FLOATS:
+      mips_disable_float_construction = 1;
+      break;
+      
     case OPTION_TRAP:
       mips_trap = 1;
       break;
@@ -9040,8 +9070,24 @@ md_parse_option (c, arg)
                if (strcmp (p, "orion") == 0)
                  mips_cpu = 4600;
                break;
-             }
 
+             case 'm':
+             case 'M':
+               switch (atoi (p + 1))
+                 {
+                 case 5200:
+                 case 5230:
+                 case 5231:
+                 case 5261:
+                 case 5721:
+                 case 7000:
+                   mips_cpu = 5000;
+                   break;
+                 default:
+                   break;
+                 }
+             }
+           
            if (sv
                && (mips_cpu != 4300
                    && mips_cpu != 4100
@@ -9319,6 +9365,7 @@ MIPS options:\n\
   fprintf(stream, _("\
 -O0                    remove unneeded NOPs, do not swap branches\n\
 -O                     remove unneeded NOPs and swap branches\n\
+--[no-]construct-floats [dis]allow floating point values to be constructed\n\
 --trap, --no-break     trap exception on div by 0 and mult overflow\n\
 --break, --no-trap     break exception on div by 0 and mult overflow\n"));
 #ifdef OBJ_ELF
@@ -9362,7 +9409,7 @@ md_pcrel_from (fixP)
 
 void
 cons_fix_new_mips (frag, where, nbytes, exp)
-     fragS *frag;
+     fragS *frag ATTRIBUTE_UNUSED;
      int where;
      unsigned int nbytes;
      expressionS *exp;
@@ -9495,6 +9542,7 @@ mips_frob_file ()
    fixup requires the special reloc.  */
 #define SWITCH_TABLE(fixp) \
   ((fixp)->fx_r_type == BFD_RELOC_32 \
+   && OUTPUT_FLAVOR != bfd_target_elf_flavour \
    && (fixp)->fx_addsy != NULL \
    && (fixp)->fx_subsy != NULL \
    && S_GET_SEGMENT ((fixp)->fx_addsy) == text_section \
@@ -9542,15 +9590,16 @@ md_apply_fix (fixP, valueP)
      symbol, we need to adjust the value.  */
 #ifdef OBJ_ELF
   if (fixP->fx_addsy != NULL && OUTPUT_FLAVOR == bfd_target_elf_flavour)
+    {
     if (S_GET_OTHER (fixP->fx_addsy) == STO_MIPS16 
         || S_IS_WEAK (fixP->fx_addsy)
         || (symbol_used_in_reloc_p (fixP->fx_addsy)
             && (((bfd_get_section_flags (stdoutput,
-                                        S_GET_SEGMENT (fixP->fx_addsy))
-                 & SEC_LINK_ONCE) != 0)
-               || !strncmp (segment_name (S_GET_SEGMENT (fixP->fx_addsy)),
-                            ".gnu.linkonce",
-                            sizeof (".gnu.linkonce") - 1))))
+                                         S_GET_SEGMENT (fixP->fx_addsy))
+                  & SEC_LINK_ONCE) != 0)
+                || !strncmp (segment_name (S_GET_SEGMENT (fixP->fx_addsy)),
+                             ".gnu.linkonce",
+                             sizeof (".gnu.linkonce") - 1))))
 
       {
         value -= S_GET_VALUE (fixP->fx_addsy);
@@ -9558,12 +9607,29 @@ md_apply_fix (fixP, valueP)
           {
             /* In this case, the bfd_install_relocation routine will
                incorrectly add the symbol value back in.  We just want
-               the addend to appear in the object file.  */
+               the addend to appear in the object file.  
+              FIXME: If this makes VALUE zero, we're toast.  */
             value -= S_GET_VALUE (fixP->fx_addsy);
           }
       }
-#endif
 
+      /* This code was generated using trial and error and so is
+        fragile and not trustworthy.  If you change it, you should
+        rerun the elf-rel, elf-rel2, and empic testcases and ensure
+        they still pass.  */
+      if (fixP->fx_pcrel || fixP->fx_subsy != NULL)
+       {
+         value += fixP->fx_frag->fr_address + fixP->fx_where;
+
+         /* BFD's REL handling, for MIPS, is _very_ weird.
+            This gives the right results, but it can't possibly
+            be the way things are supposed to work.  */
+         if (fixP->fx_r_type != BFD_RELOC_16_PCREL_S2
+             || S_GET_SEGMENT (fixP->fx_addsy) != undefined_section)
+           value += fixP->fx_frag->fr_address + fixP->fx_where;
+       }
+    }
+#endif
 
   fixP->fx_addnumber = value;  /* Remember value for tc_gen_reloc */
 
@@ -9601,7 +9667,12 @@ md_apply_fix (fixP, valueP)
     case BFD_RELOC_PCREL_HI16_S:
       /* The addend for this is tricky if it is internal, so we just
         do everything here rather than in bfd_install_relocation.  */
-      if ((symbol_get_bfdsym (fixP->fx_addsy)->flags & BSF_SECTION_SYM) == 0)
+      if (OUTPUT_FLAVOR == bfd_target_elf_flavour 
+         && !fixP->fx_done
+         && value != 0)
+       break;
+      if (fixP->fx_addsy
+         && (symbol_get_bfdsym (fixP->fx_addsy)->flags & BSF_SECTION_SYM) == 0)
        {
          /* For an external symbol adjust by the address to make it
             pcrel_offset.  We use the address of the RELLO reloc
@@ -9621,7 +9692,12 @@ md_apply_fix (fixP, valueP)
     case BFD_RELOC_PCREL_LO16:
       /* The addend for this is tricky if it is internal, so we just
         do everything here rather than in bfd_install_relocation.  */
-      if ((symbol_get_bfdsym (fixP->fx_addsy)->flags & BSF_SECTION_SYM) == 0)
+      if (OUTPUT_FLAVOR == bfd_target_elf_flavour 
+         && !fixP->fx_done
+         && value != 0)
+       break;
+      if (fixP->fx_addsy
+         && (symbol_get_bfdsym (fixP->fx_addsy)->flags & BSF_SECTION_SYM) == 0)
        value += fixP->fx_frag->fr_address + fixP->fx_where;
       buf = (unsigned char *) fixP->fx_frag->fr_literal + fixP->fx_where;
       if (target_big_endian)
@@ -9704,6 +9780,15 @@ md_apply_fix (fixP, valueP)
       if ((value & 0x3) != 0)
        as_bad_where (fixP->fx_file, fixP->fx_line,
                      _("Branch to odd address (%lx)"), value);
+
+      if (!fixP->fx_done && value != 0)
+       break;
+      /* If 'value' is zero, the remaining reloc code won't actually
+        do the store, so it must be done here.  This is probably
+        a bug somewhere.  */
+      if (!fixP->fx_done)
+       value -= fixP->fx_frag->fr_address + fixP->fx_where;
+      
       value >>= 2;
 
       /* update old instruction data */
@@ -9901,7 +9986,7 @@ mips_align (to, fill, label)
 
 static void
 s_align (x)
-     int x;
+     int x ATTRIBUTE_UNUSED;
 {
   register int temp;
   register long temp_fill;
@@ -10006,7 +10091,7 @@ s_change_sec (sec)
                                      | SEC_RELOC
                                      | SEC_DATA));
              if (strcmp (TARGET_OS, "elf") != 0)
-               bfd_set_section_alignment (stdoutput, seg, 4);
+               record_alignment (seg, 4);
            }
          demand_empty_rest_of_line ();
        }
@@ -10028,7 +10113,7 @@ s_change_sec (sec)
                                     SEC_ALLOC | SEC_LOAD | SEC_RELOC
                                     | SEC_DATA);
              if (strcmp (TARGET_OS, "elf") != 0)
-               bfd_set_section_alignment (stdoutput, seg, 4);
+               record_alignment (seg, 4);
            }
          demand_empty_rest_of_line ();
          break;
@@ -10095,7 +10180,7 @@ s_float_cons (type)
 
 static void
 s_mips_globl (x)
-     int x;
+     int x ATTRIBUTE_UNUSED;
 {
   char *name;
   int c;
@@ -10136,7 +10221,7 @@ s_mips_globl (x)
 
 static void
 s_option (x)
-     int x;
+     int x ATTRIBUTE_UNUSED;
 {
   char *opt;
   char c;
@@ -10189,7 +10274,7 @@ static struct mips_option_stack *mips_opts_stack;
 
 static void
 s_mipsset (x)
-     int x;
+     int x ATTRIBUTE_UNUSED;
 {
   char *name = input_line_pointer, ch;
 
@@ -10325,7 +10410,7 @@ s_mipsset (x)
 
 static void
 s_abicalls (ignore)
-     int ignore;
+     int ignore ATTRIBUTE_UNUSED;
 {
   mips_pic = SVR4_PIC;
   if (USE_GLOBAL_POINTER_OPT)
@@ -10350,7 +10435,7 @@ s_abicalls (ignore)
 
 static void
 s_cpload (ignore)
-     int ignore;
+     int ignore ATTRIBUTE_UNUSED;
 {
   expressionS ex;
   int icnt = 0;
@@ -10390,7 +10475,7 @@ s_cpload (ignore)
 
 static void
 s_cprestore (ignore)
-     int ignore;
+     int ignore ATTRIBUTE_UNUSED;
 {
   expressionS ex;
   int icnt = 0;
@@ -10423,7 +10508,7 @@ s_cprestore (ignore)
 
 static void
 s_gpword (ignore)
-     int ignore;
+     int ignore ATTRIBUTE_UNUSED;
 {
   symbolS *label;
   expressionS ex;
@@ -10463,7 +10548,7 @@ s_gpword (ignore)
 
 static void
 s_cpadd (ignore)
-     int ignore;
+     int ignore ATTRIBUTE_UNUSED;
 {
   int icnt = 0;
   int reg;
@@ -10497,7 +10582,7 @@ s_cpadd (ignore)
 
 static void
 s_insn (ignore)
-     int ignore;
+     int ignore ATTRIBUTE_UNUSED;
 {
   if (mips_opts.mips16)
     mips16_mark_labels ();
@@ -10526,7 +10611,7 @@ s_mips_stab (type)
 
 static void
 s_mips_weakext (ignore)
-     int ignore;
+     int ignore ATTRIBUTE_UNUSED;
 {
   char *name;
   int c;
@@ -10936,7 +11021,8 @@ md_estimate_size_before_relax (fragp, segtype)
      fragS *fragp;
      asection *segtype;
 {
-  int change;
+  int change = 0;
+  boolean linkonce = false;
 
   if (RELAX_MIPS16_P (fragp->fr_subtype))
     {
@@ -10979,10 +11065,31 @@ md_estimate_size_before_relax (fragp, segtype)
 
       symsec = S_GET_SEGMENT (sym);
 
+      /* duplicate the test for LINK_ONCE sections as in adjust_reloc_syms */
+      if (symsec != segtype && ! S_IS_LOCAL (sym))
+        {
+          if ((bfd_get_section_flags (stdoutput, symsec) & SEC_LINK_ONCE)
+              != 0)
+            linkonce = true;
+
+          /* The GNU toolchain uses an extension for ELF: a section
+             beginning with the magic string .gnu.linkonce is a linkonce
+             section.  */
+          if (strncmp (segment_name (symsec), ".gnu.linkonce",
+                       sizeof ".gnu.linkonce" - 1) == 0)
+            linkonce = true;
+        }
+
       /* This must duplicate the test in adjust_reloc_syms.  */
       change = (symsec != &bfd_und_section
                && symsec != &bfd_abs_section
-               && ! bfd_is_com_section (symsec));
+               && ! bfd_is_com_section (symsec)
+               && !linkonce
+#ifdef OBJ_ELF
+               /* A weak symbol is treated as external.  */
+               && ! S_IS_WEAK (sym)
+#endif
+               );
     }
   else
     abort ();
@@ -11039,7 +11146,7 @@ mips_fix_adjustable (fixp)
 
 arelent **
 tc_gen_reloc (section, fixp)
-     asection *section;
+     asection *section ATTRIBUTE_UNUSED;
      fixS *fixp;
 {
   static arelent *retval[4];
@@ -11064,6 +11171,8 @@ tc_gen_reloc (section, fixp)
        as_fatal (_("Double check fx_r_type in tc-mips.c:tc_gen_reloc"));
       fixp->fx_r_type = BFD_RELOC_GPREL32;
     }
+  else if (fixp->fx_pcrel == 0 || OUTPUT_FLAVOR == bfd_target_elf_flavour)
+    reloc->addend = fixp->fx_addnumber;
   else if (fixp->fx_r_type == BFD_RELOC_PCREL_LO16)
     {
       /* We use a special addend for an internal RELLO reloc.  */
@@ -11088,8 +11197,6 @@ tc_gen_reloc (section, fixp)
                         + fixp->fx_next->fx_frag->fr_address
                         + fixp->fx_next->fx_where);
     }
-  else if (fixp->fx_pcrel == 0)
-    reloc->addend = fixp->fx_addnumber;
   else
     {
       if (OUTPUT_FLAVOR != bfd_target_aout_flavour)
@@ -11228,7 +11335,8 @@ tc_gen_reloc (section, fixp)
   /* To support a PC relative reloc when generating embedded PIC code
      for ECOFF, we use a Cygnus extension.  We check for that here to
      make sure that we don't let such a reloc escape normally.  */
-  if (OUTPUT_FLAVOR == bfd_target_ecoff_flavour
+  if ((OUTPUT_FLAVOR == bfd_target_ecoff_flavour
+       || OUTPUT_FLAVOR == bfd_target_elf_flavour)
       && code == BFD_RELOC_16_PCREL_S2
       && mips_pic != EMBEDDED_PIC)
     reloc->howto = NULL;
@@ -11279,7 +11387,7 @@ mips_relax_frag (fragp, stretch)
 
 void
 md_convert_frag (abfd, asec, fragp)
-     bfd *abfd;
+     bfd *abfd ATTRIBUTE_UNUSED;
      segT asec;
      fragS *fragp;
 {
@@ -11539,7 +11647,7 @@ int
 mips_do_align (n, fill, len, max)
      int n;
      const char *fill;
-     int len;
+     int len ATTRIBUTE_UNUSED;
      int max;
 {
   if (fill == NULL
@@ -11631,7 +11739,7 @@ get_number ()
 
 static void
 s_file (x)
-     int x;
+     int x ATTRIBUTE_UNUSED;
 {
   int line;
 
@@ -11644,7 +11752,7 @@ s_file (x)
 
 static void
 s_mips_end (x)
-     int x;
+     int x ATTRIBUTE_UNUSED;
 {
   symbolS *p;
   int maybe_text;
@@ -11893,6 +12001,3 @@ s_loc (x)
   symbolP->sy_segment = now_seg;
 }
 #endif
-
-
-  
This page took 0.0358039999999999 seconds and 4 git commands to generate.