Rearrange symbol_create parameters
[deliverable/binutils-gdb.git] / gas / config / tc-mips.c
index 1c5dc7a8830b8c71eee78a6feb5b8c65058a52a5..ebcc633dd81aaf0cc573570c8d252718e0b0f6d5 100644 (file)
@@ -1,5 +1,5 @@
 /* tc-mips.c -- assemble code for a MIPS chip.
-   Copyright (C) 1993-2019 Free Software Foundation, Inc.
+   Copyright (C) 1993-2020 Free Software Foundation, Inc.
    Contributed by the OSF and Ralph Campbell.
    Written by Keith Knowles and Ralph Campbell, working independently.
    Modified for ECOFF and R4000 support by Ian Lance Taylor of Cygnus
@@ -675,13 +675,13 @@ static int g_switch_seen = 0;
 static int nopic_need_relax (symbolS *, int);
 
 /* Handle of the OPCODE hash table.  */
-static struct hash_control *op_hash = NULL;
+static htab_t op_hash = NULL;
 
 /* The opcode hash table we use for the mips16.  */
-static struct hash_control *mips16_op_hash = NULL;
+static htab_t mips16_op_hash = NULL;
 
 /* The opcode hash table we use for the microMIPS ASE.  */
-static struct hash_control *micromips_op_hash = NULL;
+static htab_t micromips_op_hash = NULL;
 
 /* This array holds the chars that always start a comment.  If the
     pre-processor is disabled, these aren't very useful.  */
@@ -812,6 +812,9 @@ static int mips_debug = 0;
    fill a branch delay slot.  */
 static struct mips_cl_insn history[1 + MAX_NOPS + MAX_LLSC_RANGE];
 
+/* The maximum number of LABELS detect for the same address.  */
+#define MAX_LABELS_SAME 10
+
 /* Arrays of operands for each instruction.  */
 #define MAX_OPERANDS 6
 struct mips_operand_array
@@ -886,11 +889,6 @@ struct mips_hi_fixup
 
 static struct mips_hi_fixup *mips_hi_fixup_list;
 
-/* The frag containing the last explicit relocation operator.
-   Null if explicit relocations have not been used.  */
-
-static fragS *prev_reloc_op_frag;
-
 /* Map mips16 register numbers to normal MIPS register numbers.  */
 
 static const unsigned int mips16_to_32_reg_map[] =
@@ -3670,7 +3668,6 @@ validate_micromips_insn (const struct mips_opcode *opc,
 void
 md_begin (void)
 {
-  const char *retval = NULL;
   int i = 0;
   int broken = 0;
 
@@ -3690,21 +3687,14 @@ md_begin (void)
   if (! bfd_set_arch_mach (stdoutput, bfd_arch_mips, file_mips_opts.arch))
     as_warn (_("could not set architecture and machine"));
 
-  op_hash = hash_new ();
+  op_hash = str_htab_create ();
 
   mips_operands = XCNEWVEC (struct mips_operand_array, NUMOPCODES);
   for (i = 0; i < NUMOPCODES;)
     {
       const char *name = mips_opcodes[i].name;
 
-      retval = hash_insert (op_hash, name, (void *) &mips_opcodes[i]);
-      if (retval != NULL)
-       {
-         fprintf (stderr, _("internal error: can't hash `%s': %s\n"),
-                  mips_opcodes[i].name, retval);
-         /* Probably a memory allocation problem?  Give up now.  */
-         as_fatal (_("broken assembler, no assembly attempted"));
-       }
+      str_hash_insert (op_hash, name, (void *) &mips_opcodes[i]);
       do
        {
          if (!validate_mips_insn (&mips_opcodes[i], 0xffffffff,
@@ -3727,7 +3717,7 @@ md_begin (void)
       while ((i < NUMOPCODES) && !strcmp (mips_opcodes[i].name, name));
     }
 
-  mips16_op_hash = hash_new ();
+  mips16_op_hash = str_htab_create ();
   mips16_operands = XCNEWVEC (struct mips_operand_array,
                              bfd_mips16_num_opcodes);
 
@@ -3736,10 +3726,7 @@ md_begin (void)
     {
       const char *name = mips16_opcodes[i].name;
 
-      retval = hash_insert (mips16_op_hash, name, (void *) &mips16_opcodes[i]);
-      if (retval != NULL)
-       as_fatal (_("internal: can't hash `%s': %s"),
-                 mips16_opcodes[i].name, retval);
+      str_hash_insert (mips16_op_hash, name, (void *) &mips16_opcodes[i]);
       do
        {
          if (!validate_mips16_insn (&mips16_opcodes[i], &mips16_operands[i]))
@@ -3755,7 +3742,7 @@ md_begin (void)
             && strcmp (mips16_opcodes[i].name, name) == 0);
     }
 
-  micromips_op_hash = hash_new ();
+  micromips_op_hash = str_htab_create ();
   micromips_operands = XCNEWVEC (struct mips_operand_array,
                                 bfd_micromips_num_opcodes);
 
@@ -3764,11 +3751,8 @@ md_begin (void)
     {
       const char *name = micromips_opcodes[i].name;
 
-      retval = hash_insert (micromips_op_hash, name,
+      str_hash_insert (micromips_op_hash, name,
                            (void *) &micromips_opcodes[i]);
-      if (retval != NULL)
-       as_fatal (_("internal: can't hash `%s': %s"),
-                 micromips_opcodes[i].name, retval);
       do
        {
          struct mips_cl_insn *micromips_nop_insn;
@@ -3805,18 +3789,18 @@ md_begin (void)
      helps us detect invalid uses of them.  */
   for (i = 0; reg_names[i].name; i++)
     symbol_table_insert (symbol_new (reg_names[i].name, reg_section,
-                                    reg_names[i].num, /* & RNUM_MASK, */
-                                    &zero_address_frag));
+                                    &zero_address_frag,
+                                    reg_names[i].num));
   if (HAVE_NEWABI)
     for (i = 0; reg_names_n32n64[i].name; i++)
       symbol_table_insert (symbol_new (reg_names_n32n64[i].name, reg_section,
-                                      reg_names_n32n64[i].num, /* & RNUM_MASK, */
-                                      &zero_address_frag));
+                                      &zero_address_frag,
+                                      reg_names_n32n64[i].num));
   else
     for (i = 0; reg_names_o32[i].name; i++)
       symbol_table_insert (symbol_new (reg_names_o32[i].name, reg_section,
-                                      reg_names_o32[i].num, /* & RNUM_MASK, */
-                                      &zero_address_frag));
+                                      &zero_address_frag,
+                                      reg_names_o32[i].num));
 
   for (i = 0; i < 32; i++)
     {
@@ -3825,17 +3809,17 @@ md_begin (void)
       /* R5900 VU0 floating-point register.  */
       sprintf (regname, "$vf%d", i);
       symbol_table_insert (symbol_new (regname, reg_section,
-                                      RTYPE_VF | i, &zero_address_frag));
+                                      &zero_address_frag, RTYPE_VF | i));
 
       /* R5900 VU0 integer register.  */
       sprintf (regname, "$vi%d", i);
       symbol_table_insert (symbol_new (regname, reg_section,
-                                      RTYPE_VI | i, &zero_address_frag));
+                                      &zero_address_frag, RTYPE_VI | i));
 
       /* MSA register.  */
       sprintf (regname, "$w%d", i);
       symbol_table_insert (symbol_new (regname, reg_section,
-                                      RTYPE_MSA | i, &zero_address_frag));
+                                      &zero_address_frag, RTYPE_MSA | i));
     }
 
   obstack_init (&mips_operand_tokens);
@@ -3859,9 +3843,9 @@ md_begin (void)
   if (strncmp (TARGET_OS, "elf", 3) != 0
       && strncmp (TARGET_OS, "vxworks", 7) != 0)
     {
-      (void) bfd_set_section_alignment (stdoutput, text_section, 4);
-      (void) bfd_set_section_alignment (stdoutput, data_section, 4);
-      (void) bfd_set_section_alignment (stdoutput, bss_section, 4);
+      bfd_set_section_alignment (text_section, 4);
+      bfd_set_section_alignment (data_section, 4);
+      bfd_set_section_alignment (bss_section, 4);
     }
 
   /* Create a .reginfo section for register masks and a .mdebug
@@ -3886,8 +3870,8 @@ md_begin (void)
       {
        sec = subseg_new (".reginfo", (subsegT) 0);
 
-       bfd_set_section_flags (stdoutput, sec, flags);
-       bfd_set_section_alignment (stdoutput, sec, HAVE_NEWABI ? 3 : 2);
+       bfd_set_section_flags (sec, flags);
+       bfd_set_section_alignment (sec, HAVE_NEWABI ? 3 : 2);
 
        mips_regmask_frag = frag_more (sizeof (Elf32_External_RegInfo));
       }
@@ -3896,8 +3880,8 @@ md_begin (void)
        /* The 64-bit ABI uses a .MIPS.options section rather than
           .reginfo section.  */
        sec = subseg_new (".MIPS.options", (subsegT) 0);
-       bfd_set_section_flags (stdoutput, sec, flags);
-       bfd_set_section_alignment (stdoutput, sec, 3);
+       bfd_set_section_flags (sec, flags);
+       bfd_set_section_alignment (sec, 3);
 
        /* Set up the option header.  */
        {
@@ -3918,25 +3902,23 @@ md_begin (void)
       }
 
     sec = subseg_new (".MIPS.abiflags", (subsegT) 0);
-    bfd_set_section_flags (stdoutput, sec,
+    bfd_set_section_flags (sec,
                           SEC_READONLY | SEC_DATA | SEC_ALLOC | SEC_LOAD);
-    bfd_set_section_alignment (stdoutput, sec, 3);
+    bfd_set_section_alignment (sec, 3);
     mips_flags_frag = frag_more (sizeof (Elf_External_ABIFlags_v0));
 
     if (ECOFF_DEBUGGING)
       {
        sec = subseg_new (".mdebug", (subsegT) 0);
-       (void) bfd_set_section_flags (stdoutput, sec,
-                                     SEC_HAS_CONTENTS | SEC_READONLY);
-       (void) bfd_set_section_alignment (stdoutput, sec, 2);
+       bfd_set_section_flags (sec, SEC_HAS_CONTENTS | SEC_READONLY);
+       bfd_set_section_alignment (sec, 2);
       }
     else if (mips_flag_pdr)
       {
        pdr_seg = subseg_new (".pdr", (subsegT) 0);
-       (void) bfd_set_section_flags (stdoutput, pdr_seg,
-                                     SEC_READONLY | SEC_RELOC
-                                     | SEC_DEBUGGING);
-       (void) bfd_set_section_alignment (stdoutput, pdr_seg, 2);
+       bfd_set_section_flags (pdr_seg,
+                              SEC_READONLY | SEC_RELOC | SEC_DEBUGGING);
+       bfd_set_section_alignment (pdr_seg, 2);
       }
 
     subseg_set (seg, subseg);
@@ -4441,9 +4423,10 @@ mips_move_labels (struct insn_label_list *labels, bfd_boolean text_p)
       gas_assert (S_GET_SEGMENT (l->label) == now_seg);
       symbol_set_frag (l->label, frag_now);
       val = (valueT) frag_now_fix ();
-      /* MIPS16/microMIPS text labels are stored as odd.  */
+      /* MIPS16/microMIPS text labels are stored as odd.
+        We just carry the ISA mode bit forward.  */
       if (text_p && HAVE_CODE_COMPRESSION)
-       ++val;
+       val |= (S_GET_VALUE (l->label) & 0x1);
       S_SET_VALUE (l->label, val);
     }
 }
@@ -4467,7 +4450,7 @@ s_is_linkonce (symbolS *sym, segT from_seg)
 
   if (symseg != from_seg && !S_IS_LOCAL (sym))
     {
-      if ((bfd_get_section_flags (stdoutput, symseg) & SEC_LINK_ONCE))
+      if ((bfd_section_flags (symseg) & SEC_LINK_ONCE))
        linkonce = TRUE;
       /* The GNU toolchain uses an extension for ELF: a section
         beginning with the magic string .gnu.linkonce is a
@@ -4776,7 +4759,7 @@ gpr_read_mask (const struct mips_cl_insn *ip)
   if (pinfo2 & INSN2_READ_SP)
     mask |= 1 << SP;
   if (pinfo2 & INSN2_READ_GPR_31)
-    mask |= 1 << 31;
+    mask |= 1u << 31;
   /* Don't include register 0.  */
   return mask & ~1;
 }
@@ -4795,7 +4778,7 @@ gpr_write_mask (const struct mips_cl_insn *ip)
   if (pinfo & INSN_WRITE_GPR_24)
     mask |= 1 << 24;
   if (pinfo & INSN_WRITE_GPR_31)
-    mask |= 1 << 31;
+    mask |= 1u << 31;
   if (pinfo & INSN_UDI)
     /* UDI instructions have traditionally been assumed to write to RD.  */
     mask |= 1 << EXTRACT_OPERAND (mips_opts.micromips, RD, *ip);
@@ -6179,7 +6162,7 @@ match_float_constant (struct mips_arg_info *arg, expressionS *imm,
     }
 
   new_seg = subseg_new (newname, (subsegT) 0);
-  bfd_set_section_flags (stdoutput, new_seg,
+  bfd_set_section_flags (new_seg,
                         SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_DATA);
   frag_align (length == 4 ? 2 : 3, 0, 0);
   if (strncmp (TARGET_OS, "elf", 3) != 0)
@@ -6902,7 +6885,21 @@ fix_loongson2f (struct mips_cl_insn * ip)
     fix_loongson2f_jump (ip);
 }
 
-/* Fix loongson3 llsc errata: Insert sync before ll/lld. */
+static bfd_boolean
+has_label_name (const char *arr[], size_t len ,const char *s)
+{
+  unsigned long i;
+  for (i = 0; i < len; i++)
+    {
+      if (!arr[i])
+       return FALSE;
+      if (streq (arr[i], s))
+       return TRUE;
+    }
+  return FALSE;
+}
+
+/* Fix loongson3 llsc errata: Insert sync before ll/lld.  */
 
 static void
 fix_loongson3_llsc (struct mips_cl_insn * ip)
@@ -6916,10 +6913,30 @@ fix_loongson3_llsc (struct mips_cl_insn * ip)
       && S_IS_LOCAL (seg_info (now_seg)->label_list->label)
       && (strcmp (ip->insn_mo->name, "sync") != 0))
     {
-      const char *label_name = S_GET_NAME (seg_info (now_seg)->label_list->label);
-      unsigned long lookback = ARRAY_SIZE (history);
       unsigned long i;
+      valueT label_value;
+      const char *label_names[MAX_LABELS_SAME];
+      const char *label_name;
 
+      label_name = S_GET_NAME (seg_info (now_seg)->label_list->label);
+      label_names[0] = label_name;
+      struct insn_label_list *llist = seg_info (now_seg)->label_list;
+      label_value = S_GET_VALUE (llist->label);
+
+      for (i = 1; i < MAX_LABELS_SAME; i++)
+       {
+         llist = llist->next;
+         if (!llist)
+           break;
+         if (S_GET_VALUE (llist->label) == label_value)
+           label_names[i] = S_GET_NAME (llist->label);
+         else
+           break;
+       }
+      for (; i < MAX_LABELS_SAME; i++)
+       label_names[i] = NULL;
+
+      unsigned long lookback = ARRAY_SIZE (history);
       for (i = 0; i < lookback; i++)
        {
          if (streq (history[i].insn_mo->name, "ll")
@@ -6939,7 +6956,9 @@ fix_loongson3_llsc (struct mips_cl_insn * ip)
 
                  if (delayed_branch_p (&history[j]))
                    {
-                     if (streq (history[j].target, label_name))
+                     if (has_label_name (label_names,
+                                         MAX_LABELS_SAME,
+                                         history[j].target))
                        {
                          add_fixed_insn (&sync_insn);
                          insert_into_history (0, 1, &sync_insn);
@@ -6953,7 +6972,7 @@ fix_loongson3_llsc (struct mips_cl_insn * ip)
     }
   /* If we find a sc, we look forward to look for an branch insn,
      and see whether it jump back and out of ll/sc.  */
-  else if (streq(ip->insn_mo->name, "sc") || streq(ip->insn_mo->name, "scd"))
+  else if (streq (ip->insn_mo->name, "sc") || streq (ip->insn_mo->name, "scd"))
     {
       unsigned long lookback = ARRAY_SIZE (history) - 1;
       unsigned long i;
@@ -8989,7 +9008,7 @@ macro_build (expressionS *ep, const char *name, const char *fmt, ...)
   bfd_reloc_code_real_type r[3];
   const struct mips_opcode *amo;
   const struct mips_operand *operand;
-  struct hash_control *hash;
+  htab_t hash;
   struct mips_cl_insn insn;
   va_list args;
   unsigned int uval;
@@ -9007,7 +9026,7 @@ macro_build (expressionS *ep, const char *name, const char *fmt, ...)
   r[1] = BFD_RELOC_UNUSED;
   r[2] = BFD_RELOC_UNUSED;
   hash = mips_opts.micromips ? micromips_op_hash : op_hash;
-  amo = (struct mips_opcode *) hash_find (hash, name);
+  amo = (struct mips_opcode *) str_hash_find (hash, name);
   gas_assert (amo);
   gas_assert (strcmp (name, amo->name) == 0);
 
@@ -9165,7 +9184,7 @@ mips16_macro_build (expressionS *ep, const char *name, const char *fmt,
   bfd_reloc_code_real_type r[3]
     = {BFD_RELOC_UNUSED, BFD_RELOC_UNUSED, BFD_RELOC_UNUSED};
 
-  mo = (struct mips_opcode *) hash_find (mips16_op_hash, name);
+  mo = (struct mips_opcode *) str_hash_find (mips16_op_hash, name);
   gas_assert (mo);
   gas_assert (strcmp (name, mo->name) == 0);
 
@@ -12780,20 +12799,28 @@ macro (struct mips_cl_insn *ip, char *str)
          OFFSET_EXPR.  */
       if (imm_expr.X_op == O_constant)
        {
-         used_at = 1;
-         load_register (AT, &imm_expr, FPR_SIZE == 64);
+         tempreg = ZERO;
+         if (((FPR_SIZE == 64 && GPR_SIZE == 64)
+              || !ISA_HAS_MXHC1 (mips_opts.isa))
+             && imm_expr.X_add_number != 0)
+           {
+             used_at = 1;
+             tempreg = AT;
+             load_register (AT, &imm_expr, FPR_SIZE == 64);
+           }
          if (FPR_SIZE == 64 && GPR_SIZE == 64)
-           macro_build (NULL, "dmtc1", "t,S", AT, op[0]);
+           macro_build (NULL, "dmtc1", "t,S", tempreg, op[0]);
          else
            {
-             if (ISA_HAS_MXHC1 (mips_opts.isa))
-               macro_build (NULL, "mthc1", "t,G", AT, op[0]);
-             else if (FPR_SIZE != 32)
-               as_bad (_("Unable to generate `%s' compliant code "
-                         "without mthc1"),
-                       (FPR_SIZE == 64) ? "fp64" : "fpxx");
-             else
-               macro_build (NULL, "mtc1", "t,G", AT, op[0] + 1);
+             if (!ISA_HAS_MXHC1 (mips_opts.isa))
+               {
+                 if (FPR_SIZE != 32)
+                   as_bad (_("Unable to generate `%s' compliant code "
+                             "without mthc1"),
+                           (FPR_SIZE == 64) ? "fp64" : "fpxx");
+                 else
+                   macro_build (NULL, "mtc1", "t,G", tempreg, op[0] + 1);
+               }
              if (offset_expr.X_op == O_absent)
                macro_build (NULL, "mtc1", "t,G", 0, op[0]);
              else
@@ -12802,6 +12829,16 @@ macro (struct mips_cl_insn *ip, char *str)
                  load_register (AT, &offset_expr, 0);
                  macro_build (NULL, "mtc1", "t,G", AT, op[0]);
                }
+             if (ISA_HAS_MXHC1 (mips_opts.isa))
+               {
+                 if (imm_expr.X_add_number != 0)
+                   {
+                     used_at = 1;
+                     tempreg = AT;
+                     load_register (AT, &imm_expr, 0);
+                   }
+                 macro_build (NULL, "mthc1", "t,G", tempreg, op[0]);
+               }
            }
          break;
        }
@@ -14207,7 +14244,7 @@ mips16_macro (struct mips_cl_insn *ip)
    opcode bits in *OPCODE_EXTRA.  */
 
 static struct mips_opcode *
-mips_lookup_insn (struct hash_control *hash, const char *start,
+mips_lookup_insn (htab_t hash, const char *start,
                  ssize_t length, unsigned int *opcode_extra)
 {
   char *name, *dot, *p;
@@ -14219,7 +14256,7 @@ mips_lookup_insn (struct hash_control *hash, const char *start,
   name = xstrndup (start, length);
 
   /* Look up the instruction as-is.  */
-  insn = (struct mips_opcode *) hash_find (hash, name);
+  insn = (struct mips_opcode *) str_hash_find (hash, name);
   if (insn)
     goto end;
 
@@ -14231,7 +14268,7 @@ mips_lookup_insn (struct hash_control *hash, const char *start,
       if (*p == 0 && mask != 0)
        {
          *dot = 0;
-         insn = (struct mips_opcode *) hash_find (hash, name);
+         insn = (struct mips_opcode *) str_hash_find (hash, name);
          *dot = '.';
          if (insn && (insn->pinfo2 & INSN2_VU0_CHANNEL_SUFFIX) != 0)
            {
@@ -14257,7 +14294,7 @@ mips_lookup_insn (struct hash_control *hash, const char *start,
       if (suffix)
        {
          memmove (name + opend - 2, name + opend, length - opend + 1);
-         insn = (struct mips_opcode *) hash_find (hash, name);
+         insn = (struct mips_opcode *) str_hash_find (hash, name);
          if (insn)
            {
              forced_insn_length = suffix;
@@ -14282,7 +14319,7 @@ static void
 mips_ip (char *str, struct mips_cl_insn *insn)
 {
   const struct mips_opcode *first, *past;
-  struct hash_control *hash;
+  htab_t hash;
   char format;
   size_t end;
   struct mips_operand_token *tokens;
@@ -14378,7 +14415,7 @@ mips16_ip (char *str, struct mips_cl_insn *insn)
   forced_insn_length = l;
 
   *end = 0;
-  first = (struct mips_opcode *) hash_find (mips16_op_hash, str);
+  first = (struct mips_opcode *) str_hash_find (mips16_op_hash, str);
   *end = c;
 
   if (!first)
@@ -14664,12 +14701,8 @@ my_getSmallExpression (expressionS *ep, bfd_reloc_code_real_type *reloc,
 
   expr_end = str;
 
-  if (reloc_index != 0)
-    {
-      prev_reloc_op_frag = frag_now;
-      for (i = 0; i < reloc_index; i++)
-       reloc[i] = reversed_reloc[reloc_index - 1 - i];
-    }
+  for (i = 0; i < reloc_index; i++)
+    reloc[i] = reversed_reloc[reloc_index - 1 - i];
 
   return reloc_index;
 }
@@ -15724,6 +15757,24 @@ fix_bad_misaligned_branch_p (fixS *fixP)
   return (val & 0x3) != isa_bit;
 }
 
+/* Calculate the relocation target by masking off ISA mode bit before
+   combining symbol and addend.  */
+
+static valueT
+fix_bad_misaligned_address (fixS *fixP)
+{
+  valueT val;
+  valueT off;
+  unsigned isa_mode;
+  gas_assert (fixP != NULL && fixP->fx_addsy != NULL);
+  val = S_GET_VALUE (fixP->fx_addsy);
+  off = fixP->fx_offset;
+  isa_mode = (ELF_ST_IS_COMPRESSED (S_GET_OTHER (fixP->fx_addsy))
+             ? 1 : 0);
+
+  return ((val & ~isa_mode) + off);
+}
+
 /* Make the necessary checks on a regular MIPS branch pointed to by FIXP
    and its calculated value VAL.  */
 
@@ -15740,7 +15791,7 @@ fix_validate_branch (fixS *fixP, valueT val)
   else if (fix_bad_misaligned_branch_p (fixP))
     as_bad_where (fixP->fx_file, fixP->fx_line,
                  _("branch to misaligned address (0x%lx)"),
-                 (long) (S_GET_VALUE (fixP->fx_addsy) + fixP->fx_offset));
+                 (long) fix_bad_misaligned_address (fixP));
   else if (HAVE_IN_PLACE_ADDENDS && (fixP->fx_offset & 0x3) != 0)
     as_bad_where (fixP->fx_file, fixP->fx_line,
                  _("cannot encode misaligned addend "
@@ -15879,8 +15930,7 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
        else if (fix_bad_misaligned_jump_p (fixP, shift))
          as_bad_where (fixP->fx_file, fixP->fx_line,
                        _("jump to misaligned address (0x%lx)"),
-                       (long) (S_GET_VALUE (fixP->fx_addsy)
-                               + fixP->fx_offset));
+                       (long) fix_bad_misaligned_address (fixP));
        else if (HAVE_IN_PLACE_ADDENDS
                 && (fixP->fx_offset & ((1 << shift) - 1)) != 0)
          as_bad_where (fixP->fx_file, fixP->fx_line,
@@ -16092,7 +16142,7 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
               && fixP->fx_done
               && fixP->fx_frag->fr_address >= text_section->vma
               && (fixP->fx_frag->fr_address
-                  < text_section->vma + bfd_get_section_size (text_section))
+                  < text_section->vma + bfd_section_size (text_section))
               && ((insn & 0xffff0000) == 0x10000000     /* beq $0,$0 */
                   || (insn & 0xffff0000) == 0x04010000  /* bgez $0 */
                   || (insn & 0xffff0000) == 0x04110000)) /* bgezal $0 */
@@ -16134,7 +16184,7 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
               && (fixP->fx_offset & 0x1) != 0)
        as_bad_where (fixP->fx_file, fixP->fx_line,
                      _("branch to misaligned address (0x%lx)"),
-                     (long) (S_GET_VALUE (fixP->fx_addsy) + fixP->fx_offset));
+                     (long) fix_bad_misaligned_address (fixP));
       else if (HAVE_IN_PLACE_ADDENDS && (fixP->fx_offset & 0x1) != 0)
        as_bad_where (fixP->fx_file, fixP->fx_line,
                      _("cannot encode misaligned addend "
@@ -16200,7 +16250,7 @@ mips_align (int to, int *fill, struct insn_label_list *labels)
   else
     frag_align (to, fill ? *fill : 0, 0);
   record_alignment (now_seg, to);
-  mips_move_labels (labels, FALSE);
+  mips_move_labels (labels, subseg_text_p (now_seg));
 }
 
 /* Align to a given power of two.  .align 0 turns off the automatic
@@ -16283,9 +16333,8 @@ s_change_sec (int sec)
     case 'r':
       seg = subseg_new (RDATA_SECTION_NAME,
                        (subsegT) get_absolute_expression ());
-      bfd_set_section_flags (stdoutput, seg, (SEC_ALLOC | SEC_LOAD
-                                             | SEC_READONLY | SEC_RELOC
-                                             | SEC_DATA));
+      bfd_set_section_flags (seg, (SEC_ALLOC | SEC_LOAD | SEC_READONLY
+                                  | SEC_RELOC | SEC_DATA));
       if (strncmp (TARGET_OS, "elf", 3) != 0)
        record_alignment (seg, 4);
       demand_empty_rest_of_line ();
@@ -16293,8 +16342,8 @@ s_change_sec (int sec)
 
     case 's':
       seg = subseg_new (".sdata", (subsegT) get_absolute_expression ());
-      bfd_set_section_flags (stdoutput, seg,
-                            SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_DATA);
+      bfd_set_section_flags (seg, (SEC_ALLOC | SEC_LOAD | SEC_RELOC
+                                  | SEC_DATA | SEC_SMALL_DATA));
       if (strncmp (TARGET_OS, "elf", 3) != 0)
        record_alignment (seg, 4);
       demand_empty_rest_of_line ();
@@ -16302,7 +16351,7 @@ s_change_sec (int sec)
 
     case 'B':
       seg = subseg_new (".sbss", (subsegT) get_absolute_expression ());
-      bfd_set_section_flags (stdoutput, seg, SEC_ALLOC);
+      bfd_set_section_flags (seg, SEC_ALLOC | SEC_SMALL_DATA);
       if (strncmp (TARGET_OS, "elf", 3) != 0)
        record_alignment (seg, 4);
       demand_empty_rest_of_line ();
@@ -16385,7 +16434,7 @@ s_change_section (int ignore ATTRIBUTE_UNUSED)
   if (section_type == SHT_MIPS_DWARF)
     section_type = SHT_PROGBITS;
 
-  obj_elf_change_section (section_name, section_type, 0, section_flag,
+  obj_elf_change_section (section_name, section_type, section_flag,
                          section_entry_size, 0, 0, 0);
 
   if (now_seg->name != section_name)
@@ -16443,7 +16492,6 @@ s_mips_globl (int x ATTRIBUTE_UNUSED)
   char *name;
   int c;
   symbolS *symbolP;
-  flagword flag;
 
   do
     {
@@ -16454,10 +16502,6 @@ s_mips_globl (int x ATTRIBUTE_UNUSED)
       *input_line_pointer = c;
       SKIP_WHITESPACE_AFTER_NAME ();
 
-      /* On Irix 5, every global symbol that is not explicitly labelled as
-         being a function is apparently labelled as being an object.  */
-      flag = BSF_OBJECT;
-
       if (!is_end_of_line[(unsigned char) *input_line_pointer]
          && (*input_line_pointer != ','))
        {
@@ -16471,11 +16515,9 @@ s_mips_globl (int x ATTRIBUTE_UNUSED)
          (void) restore_line_pointer (c);
 
          if (sec != NULL && (sec->flags & SEC_CODE) != 0)
-           flag = BSF_FUNCTION;
+           symbol_get_bfdsym (symbolP)->flags |= BSF_FUNCTION;
        }
 
-      symbol_get_bfdsym (symbolP)->flags |= flag;
-
       c = *input_line_pointer;
       if (c == ',')
        {
@@ -16490,6 +16532,23 @@ s_mips_globl (int x ATTRIBUTE_UNUSED)
   demand_empty_rest_of_line ();
 }
 
+#ifdef TE_IRIX
+/* The Irix 5 and 6 assemblers set the type of any common symbol and
+   any undefined non-function symbol to STT_OBJECT.  We try to be
+   compatible, since newer Irix 5 and 6 linkers care.  */
+
+void
+mips_frob_symbol (symbolS *symp ATTRIBUTE_UNUSED)
+{
+  /* This late in assembly we can set BSF_OBJECT indiscriminately
+     and let elf.c:swap_out_syms sort out the symbol type.  */
+  flagword *flags = &symbol_get_bfdsym (symp)->flags;
+  if ((*flags & (BSF_GLOBAL | BSF_WEAK)) != 0
+      || !S_IS_DEFINED (symp))
+    *flags |= BSF_OBJECT;
+}
+#endif
+
 static void
 s_option (int x ATTRIBUTE_UNUSED)
 {
@@ -17557,7 +17616,7 @@ tc_get_register (int frame)
 valueT
 md_section_align (asection *seg, valueT addr)
 {
-  int align = bfd_get_section_alignment (stdoutput, seg);
+  int align = bfd_section_alignment (seg);
 
   /* We don't need to align ELF sections to the full alignment.
      However, Irix 5 may prefer that we align them at least to a 16
@@ -18817,7 +18876,7 @@ md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT asec, fragS *fragp)
            }
 
          /* Make a label at the end for use with the branch.  */
-         l = symbol_new (micromips_label_name (), asec, fragp->fr_fix, fragp);
+         l = symbol_new (micromips_label_name (), asec, fragp, fragp->fr_fix);
          micromips_label_inc ();
          S_SET_OTHER (l, ELF_ST_SET_MICROMIPS (S_GET_OTHER (l)));
 
@@ -18971,7 +19030,8 @@ md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT asec, fragS *fragp)
              else if ((fragp->fr_offset & 0x1) != 0)
                as_bad_where (fragp->fr_file, fragp->fr_line,
                              _("branch to misaligned address (0x%lx)"),
-                             (long) val);
+                             (long) (resolve_symbol_value (fragp->fr_symbol)
+                                     + (fragp->fr_offset & ~1)));
            }
 
          val = mips16_pcrel_val (fragp, pcrel_op, val, 0);
@@ -19713,7 +19773,7 @@ s_mips_end (int x ATTRIBUTE_UNUSED)
   else
     p = NULL;
 
-  if ((bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE) == 0)
+  if ((bfd_section_flags (now_seg) & SEC_CODE) == 0)
     as_warn (_(".end not in text section"));
 
   if (!cur_proc_ptr)
@@ -19803,7 +19863,7 @@ s_mips_ent (int aent)
       || *input_line_pointer == '-')
     get_number ();
 
-  if ((bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE) == 0)
+  if ((bfd_section_flags (now_seg) & SEC_CODE) == 0)
     as_warn (_(".ent or .aent not in text section"));
 
   if (!aent && cur_proc_ptr)
This page took 0.038275 seconds and 4 git commands to generate.