* gdb.threads/bp_in_thread.exp: New testcase.
[deliverable/binutils-gdb.git] / gas / config / tc-mips.c
index c554ba16b8e0489dfb01e8e9884e74d12c7b509d..fd76eabb5ac80dd9b380a8690073cfb0b3628118 100644 (file)
@@ -2083,7 +2083,7 @@ append_insn (struct mips_cl_insn *ip, expressionS *address_expr,
     }
 
   fixp[0] = fixp[1] = fixp[2] = NULL;
-  if (address_expr != NULL && *reloc_type < BFD_RELOC_UNUSED)
+  if (address_expr != NULL && *reloc_type <= BFD_RELOC_UNUSED)
     {
       if (address_expr->X_op == O_constant)
        {
@@ -2116,6 +2116,7 @@ append_insn (struct mips_cl_insn *ip, expressionS *address_expr,
              ip->insn_opcode |= (address_expr->X_add_number >> 16) & 0xffff;
              break;
 
+           case BFD_RELOC_UNUSED:
            case BFD_RELOC_LO16:
            case BFD_RELOC_MIPS_GOT_DISP:
              ip->insn_opcode |= address_expr->X_add_number & 0xffff;
@@ -2151,7 +2152,7 @@ append_insn (struct mips_cl_insn *ip, expressionS *address_expr,
              internalError ();
            }
        }
-      else
+      else if (*reloc_type < BFD_RELOC_UNUSED)
        need_reloc:
        {
          reloc_howto_type *howto;
@@ -2710,6 +2711,7 @@ append_insn (struct mips_cl_insn *ip, expressionS *address_expr,
          prev_insn_reloc_type[1] = BFD_RELOC_UNUSED;
          prev_insn_reloc_type[2] = BFD_RELOC_UNUSED;
          prev_insn_extended = 0;
+         prev_insn_is_delay_slot = 1;
        }
       else
        {
@@ -8600,6 +8602,7 @@ do_msbd:
                          ip->insn_opcode |= (imm_expr.X_add_number
                                              << (OP_SH_VSEL +
                                                  (is_qh ? 2 : 1)));
+                         imm_expr.X_op = O_absent;
                          if (*s != ']')
                            as_warn(_("Expecting ']' found '%s'"), s);
                          else
@@ -9813,7 +9816,7 @@ parse_relocation (char **str, bfd_reloc_code_real_type *reloc)
          {
            as_bad ("relocation %s isn't supported by the current ABI",
                    percent_op[i].str);
-           *reloc = BFD_RELOC_LO16;
+           *reloc = BFD_RELOC_UNUSED;
          }
        return TRUE;
       }
@@ -9825,8 +9828,7 @@ parse_relocation (char **str, bfd_reloc_code_real_type *reloc)
    expression in *EP and the relocations in the array starting
    at RELOC.  Return the number of relocation operators used.
 
-   On exit, EXPR_END points to the first character after the expression.
-   If no relocation operators are used, RELOC[0] is set to BFD_RELOC_LO16.  */
+   On exit, EXPR_END points to the first character after the expression.  */
 
 static size_t
 my_getSmallExpression (expressionS *ep, bfd_reloc_code_real_type *reloc,
@@ -9872,9 +9874,7 @@ my_getSmallExpression (expressionS *ep, bfd_reloc_code_real_type *reloc,
 
   expr_end = str;
 
-  if (reloc_index == 0)
-    reloc[0] = BFD_RELOC_LO16;
-  else
+  if (reloc_index != 0)
     {
       prev_reloc_op_frag = frag_now;
       for (i = 0; i < reloc_index; i++)
@@ -12733,15 +12733,13 @@ md_estimate_size_before_relax (fragS *fragp, asection *segtype)
 }
 
 /* This is called to see whether a reloc against a defined symbol
-   should be converted into a reloc against a section.  Don't adjust
-   MIPS16 jump relocations, so we don't have to worry about the format
-   of the offset in the .o file.  Don't adjust relocations against
-   mips16 symbols, so that the linker can find them if it needs to set
-   up a stub.  */
+   should be converted into a reloc against a section.  */
 
 int
 mips_fix_adjustable (fixS *fixp)
 {
+  /* Don't adjust MIPS16 jump relocations, so we don't have to worry
+     about the format of the offset in the .o file. */
   if (fixp->fx_r_type == BFD_RELOC_MIPS16_JMP)
     return 0;
 
@@ -12752,7 +12750,28 @@ mips_fix_adjustable (fixS *fixp)
   if (fixp->fx_addsy == NULL)
     return 1;
 
+  /* If symbol SYM is in a mergeable section, relocations of the form
+     SYM + 0 can usually be made section-relative.  The mergeable data
+     is then identified by the section offset rather than by the symbol.
+
+     However, if we're generating REL LO16 relocations, the offset is split
+     between the LO16 and parterning high part relocation.  The linker will
+     need to recalculate the complete offset in order to correctly identify
+     the merge data.
+
+     The linker has traditionally not looked for the parterning high part
+     relocation, and has thus allowed orphaned R_MIPS_LO16 relocations to be
+     placed anywhere.  Rather than break backwards compatibility by changing
+     this, it seems better not to force the issue, and instead keep the
+     original symbol.  This will work with either linker behavior.  */
+  if ((fixp->fx_r_type == BFD_RELOC_LO16 || reloc_needs_lo_p (fixp->fx_r_type))
+      && HAVE_IN_PLACE_ADDENDS
+      && (S_GET_SEGMENT (fixp->fx_addsy)->flags & SEC_MERGE) != 0)
+    return 0;
+
 #ifdef OBJ_ELF
+  /* Don't adjust relocations against mips16 symbols, so that the linker
+     can find them if it needs to set up a stub.  */
   if (OUTPUT_FLAVOR == bfd_target_elf_flavour
       && S_GET_OTHER (fixp->fx_addsy) == STO_MIPS16
       && fixp->fx_subsy == NULL)
This page took 0.028647 seconds and 4 git commands to generate.