[AArch64] Add support for :tlsdesc: and TLSDESC_ADR_PREL21
[deliverable/binutils-gdb.git] / gas / config / tc-mn10300.c
index 5068904f0120cb8a9f8fd3f44a7ba824d08c119c..1a244aba897bc871efd5fee38e4a5d1b7e42cc40 100644 (file)
@@ -1,6 +1,5 @@
 /* tc-mn10300.c -- Assembler code for the Matsushita 10300
-   Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
-   2006, 2007 Free Software Foundation, Inc.
+   Copyright (C) 1996-2015 Free Software Foundation, Inc.
 
    This file is part of GAS, the GNU Assembler.
 
@@ -281,6 +280,8 @@ static const struct reg_name other_registers[] =
   { "pc", AM33 },
   { "psw", 0 },
   { "sp", 0 },
+  { "ssp", 0 },
+  { "usp", 0 },
 };
 
 #define OTHER_REG_NAME_CNT     ARRAY_SIZE (other_registers)
@@ -689,6 +690,8 @@ md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED,
       fragP->fr_literal[offset] = 0xdd;
       fragP->fr_literal[offset + 5] = fragP->fr_literal[offset + 3];
       fragP->fr_literal[offset + 6] = fragP->fr_literal[offset + 4];
+      fragP->fr_literal[offset + 3] = 0;
+      fragP->fr_literal[offset + 4] = 0;
 
       fix_new (fragP, fragP->fr_fix + 1, 4, fragP->fr_symbol,
               fragP->fr_offset + 1, 1, BFD_RELOC_32_PCREL);
@@ -1010,7 +1013,8 @@ mn10300_check_fixup (struct mn10300_fixup *fixup)
 }
 
 void
-mn10300_cons_fix_new (fragS *frag, int off, int size, expressionS *exp)
+mn10300_cons_fix_new (fragS *frag, int off, int size, expressionS *exp,
+                     bfd_reloc_code_real_type r ATTRIBUTE_UNUSED)
 {
   struct mn10300_fixup fixup;
 
@@ -1772,8 +1776,6 @@ keep_going:
         that they do indeed not match.  */
       if (opcode->no_match_operands)
        {
-         int i;
-
          /* Look at each operand to see if it's marked.  */
          for (i = 0; i < MN10300_MAX_OPERANDS; i++)
            {
@@ -2056,18 +2058,23 @@ keep_going:
       for (i = 0; i < fc; i++)
        {
          const struct mn10300_operand *operand;
+         int reloc_size;
 
          operand = &mn10300_operands[fixups[i].opindex];
          if (fixups[i].reloc != BFD_RELOC_UNUSED
              && fixups[i].reloc != BFD_RELOC_32_GOT_PCREL
              && fixups[i].reloc != BFD_RELOC_32_GOTOFF
              && fixups[i].reloc != BFD_RELOC_32_PLT_PCREL
+             && fixups[i].reloc != BFD_RELOC_MN10300_TLS_GD
+             && fixups[i].reloc != BFD_RELOC_MN10300_TLS_LD
+             && fixups[i].reloc != BFD_RELOC_MN10300_TLS_LDO
+             && fixups[i].reloc != BFD_RELOC_MN10300_TLS_GOTIE
+             && fixups[i].reloc != BFD_RELOC_MN10300_TLS_IE
+             && fixups[i].reloc != BFD_RELOC_MN10300_TLS_LE
              && fixups[i].reloc != BFD_RELOC_MN10300_GOT32)
            {
              reloc_howto_type *reloc_howto;
-             int size;
              int offset;
-             fixS *fixP;
 
              reloc_howto = bfd_reloc_type_lookup (stdoutput,
                                                   fixups[i].reloc);
@@ -2075,20 +2082,20 @@ keep_going:
              if (!reloc_howto)
                abort ();
 
-             size = bfd_get_reloc_size (reloc_howto);
+             reloc_size = bfd_get_reloc_size (reloc_howto);
 
-             if (size < 1 || size > 4)
+             if (reloc_size < 1 || reloc_size > 4)
                abort ();
 
              offset = 4 - size;
-             fixP = fix_new_exp (frag_now, f - frag_now->fr_literal + offset,
-                                 size, &fixups[i].exp,
-                                 reloc_howto->pc_relative,
-                                 fixups[i].reloc);
+             fix_new_exp (frag_now, f - frag_now->fr_literal + offset,
+                          reloc_size, &fixups[i].exp,
+                          reloc_howto->pc_relative,
+                          fixups[i].reloc);
            }
          else
            {
-             int reloc, pcrel, reloc_size, offset;
+             int reloc, pcrel, offset;
              fixS *fixP;
 
              reloc = BFD_RELOC_NONE;
@@ -2192,8 +2199,6 @@ tc_gen_reloc (asection *seg ATTRIBUTE_UNUSED, fixS *fixp)
       asec = S_GET_SEGMENT (fixp->fx_addsy);
       ssec = S_GET_SEGMENT (fixp->fx_subsy);
 
-      reloc->sym_ptr_ptr = NULL;
-
       /* If we have a difference between two (non-absolute) symbols we must
         generate two relocs (one for each symbol) and allow the linker to
         resolve them - relaxation may change the distances between symbols,
@@ -2213,10 +2218,15 @@ tc_gen_reloc (asection *seg ATTRIBUTE_UNUSED, fixS *fixp)
 
          reloc->addend = fixp->fx_offset; 
          if (asec == absolute_section)
-           reloc->addend += S_GET_VALUE (fixp->fx_addsy);
-
-         reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
-         *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
+           {
+             reloc->addend += S_GET_VALUE (fixp->fx_addsy);
+             reloc->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
+           }
+         else
+           {
+             reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
+             *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
+           }
 
          fixp->fx_pcrel = 0;
          fixp->fx_done = 1;
@@ -2253,8 +2263,6 @@ tc_gen_reloc (asection *seg ATTRIBUTE_UNUSED, fixS *fixp)
              return relocs;
            }
 
-         if (reloc->sym_ptr_ptr)
-           free (reloc->sym_ptr_ptr);
          free (reloc);
          return & no_relocs;
        }
@@ -2322,7 +2330,7 @@ md_apply_fix (fixS * fixP, valueT * valP, segT seg)
   int size = 0;
   int value = (int) * valP;
 
-  assert (fixP->fx_r_type < BFD_RELOC_UNUSED);
+  gas_assert (fixP->fx_r_type < BFD_RELOC_UNUSED);
 
   /* This should never happen.  */
   if (seg->flags & SEC_ALLOC)
@@ -2501,6 +2509,18 @@ mn10300_parse_name (char const *name,
     reloc_type = BFD_RELOC_MN10300_GOT32;
   else if ((next_end = mn10300_end_of_match (next + 1, "PLT")))
     reloc_type = BFD_RELOC_32_PLT_PCREL;
+  else if ((next_end = mn10300_end_of_match (next + 1, "tlsgd")))
+    reloc_type = BFD_RELOC_MN10300_TLS_GD;
+  else if ((next_end = mn10300_end_of_match (next + 1, "tlsldm")))
+    reloc_type = BFD_RELOC_MN10300_TLS_LD;
+  else if ((next_end = mn10300_end_of_match (next + 1, "dtpoff")))
+    reloc_type = BFD_RELOC_MN10300_TLS_LDO;
+  else if ((next_end = mn10300_end_of_match (next + 1, "gotntpoff")))
+    reloc_type = BFD_RELOC_MN10300_TLS_GOTIE;
+  else if ((next_end = mn10300_end_of_match (next + 1, "indntpoff")))
+    reloc_type = BFD_RELOC_MN10300_TLS_IE;
+  else if ((next_end = mn10300_end_of_match (next + 1, "tpoff")))
+    reloc_type = BFD_RELOC_MN10300_TLS_LE;
   else
     goto no_suffix;
 
This page took 0.036229 seconds and 4 git commands to generate.