]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blobdiff - gas/config/tc-mn10300.c
Update year range in copyright notice of binutils files
[thirdparty/binutils-gdb.git] / gas / config / tc-mn10300.c
index 74ede3ae55b5a8e344b9bd28416646337a7103e9..2f2e956d5a261a88b7aea4ff834dee08860124b6 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, 2008, 2009, 2010 Free Software Foundation, Inc.
+   Copyright (C) 1996-2021 Free Software Foundation, Inc.
 
    This file is part of GAS, the GNU Assembler.
 
@@ -90,9 +89,6 @@ const relax_typeS md_relax_table[] =
 
 };
 
-/*  Set linkrelax here to avoid fixups in most sections.  */
-int linkrelax = 1;
-
 static int current_machine;
 
 /* Fixups.  */
@@ -125,7 +121,7 @@ size_t md_longopts_size = sizeof (md_longopts);
 #define HAVE_AM30   (current_machine == AM30)
 
 /* Opcode hash table.  */
-static struct hash_control *mn10300_hash;
+static htab_t mn10300_hash;
 
 /* This table is sorted. Suitable for searching by a binary search.  */
 static const struct reg_name data_registers[] =
@@ -281,12 +277,14 @@ 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)
 
 /* Perform a binary search of the given register table REGS to see
-   if NAME is a valid regiter name.  Returns the register number from
+   if NAME is a valid register name.  Returns the register number from
    the array on success, or -1 on failure.  */
 
 static int
@@ -336,13 +334,13 @@ get_register_name (expressionS *           expressionP,
   char c;
 
   /* Find the spelling of the operand.  */
-  start = name = input_line_pointer;
+  start = input_line_pointer;
 
-  c = get_symbol_end ();
+  c = get_symbol_name (&name);
   reg_number = reg_name_search (table, table_length, name);
 
   /* Put back the delimiting char.  */
-  *input_line_pointer = c;
+  (void) restore_line_pointer (c);
 
   /* Look to see if it's in the register table.  */
   if (reg_number >= 0)
@@ -408,13 +406,13 @@ other_register_name (expressionS *expressionP)
   char c;
 
   /* Find the spelling of the operand.  */
-  start = name = input_line_pointer;
+  start = input_line_pointer;
 
-  c = get_symbol_end ();
+  c = get_symbol_name (&name);
   reg_number = reg_name_search (other_registers, ARRAY_SIZE (other_registers), name);
 
   /* Put back the delimiting char.  */
-  *input_line_pointer = c;
+  (void) restore_line_pointer (c);
 
   /* Look to see if it's in the register table.  */
   if (reg_number == 0
@@ -443,7 +441,7 @@ none yet\n"));
 }
 
 int
-md_parse_option (int c ATTRIBUTE_UNUSED, char *arg ATTRIBUTE_UNUSED)
+md_parse_option (int c ATTRIBUTE_UNUSED, const char *arg ATTRIBUTE_UNUSED)
 {
   return 0;
 }
@@ -454,7 +452,7 @@ md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
   return 0;
 }
 
-char *
+const char *
 md_atof (int type, char *litp, int *sizep)
 {
   return ieee_md_atof (type, litp, sizep, FALSE);
@@ -522,7 +520,7 @@ md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED,
       /* Create a fixup for the reversed conditional branch.  */
       sprintf (buf, ".%s_%ld", FAKE_LABEL_NAME, label_count++);
       fix_new (fragP, fragP->fr_fix + 1, 1,
-              symbol_new (buf, sec, 0, fragP->fr_next),
+              symbol_new (buf, sec, fragP->fr_next, 0),
               fragP->fr_offset + 1, 1, BFD_RELOC_8_PCREL);
 
       /* Now create the unconditional branch + fixup to the
@@ -579,7 +577,7 @@ md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED,
       /* Create a fixup for the reversed conditional branch.  */
       sprintf (buf, ".%s_%ld", FAKE_LABEL_NAME, label_count++);
       fix_new (fragP, fragP->fr_fix + 1, 1,
-              symbol_new (buf, sec, 0, fragP->fr_next),
+              symbol_new (buf, sec, fragP->fr_next, 0),
               fragP->fr_offset + 1, 1, BFD_RELOC_8_PCREL);
 
       /* Now create the unconditional branch + fixup to the
@@ -625,7 +623,7 @@ md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED,
       /* Create a fixup for the reversed conditional branch.  */
       sprintf (buf, ".%s_%ld", FAKE_LABEL_NAME, label_count++);
       fix_new (fragP, fragP->fr_fix + 2, 1,
-              symbol_new (buf, sec, 0, fragP->fr_next),
+              symbol_new (buf, sec, fragP->fr_next, 0),
               fragP->fr_offset + 2, 1, BFD_RELOC_8_PCREL);
 
       /* Now create the unconditional branch + fixup to the
@@ -661,7 +659,7 @@ md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED,
       /* Create a fixup for the reversed conditional branch.  */
       sprintf (buf, ".%s_%ld", FAKE_LABEL_NAME, label_count++);
       fix_new (fragP, fragP->fr_fix + 2, 1,
-              symbol_new (buf, sec, 0, fragP->fr_next),
+              symbol_new (buf, sec, fragP->fr_next, 0),
               fragP->fr_offset + 2, 1, BFD_RELOC_8_PCREL);
 
       /* Now create the unconditional branch + fixup to the
@@ -689,6 +687,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);
@@ -813,7 +813,7 @@ md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED,
       /* Create a fixup for the reversed conditional branch.  */
       sprintf (buf, ".%s_%ld", FAKE_LABEL_NAME, label_count++);
       fix_new (fragP, fragP->fr_fix + 2, 1,
-              symbol_new (buf, sec, 0, fragP->fr_next),
+              symbol_new (buf, sec, fragP->fr_next, 0),
               fragP->fr_offset + 2, 1, BFD_RELOC_8_PCREL);
 
       /* Now create the unconditional branch + fixup to the
@@ -882,7 +882,7 @@ md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED,
       /* Create a fixup for the reversed conditional branch.  */
       sprintf (buf, ".%s_%ld", FAKE_LABEL_NAME, label_count++);
       fix_new (fragP, fragP->fr_fix + 2, 1,
-              symbol_new (buf, sec, 0, fragP->fr_next),
+              symbol_new (buf, sec, fragP->fr_next, 0),
               fragP->fr_offset + 2, 1, BFD_RELOC_8_PCREL);
 
       /* Now create the unconditional branch + fixup to the
@@ -900,18 +900,18 @@ md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED,
 valueT
 md_section_align (asection *seg, valueT addr)
 {
-  int align = bfd_get_section_alignment (stdoutput, seg);
+  int align = bfd_section_alignment (seg);
 
-  return ((addr + (1 << align) - 1) & (-1 << align));
+  return ((addr + (1 << align) - 1) & -(1 << align));
 }
 
 void
 md_begin (void)
 {
-  char *prev_name = "";
+  const char *prev_name = "";
   const struct mn10300_opcode *op;
 
-  mn10300_hash = hash_new ();
+  mn10300_hash = str_htab_create ();
 
   /* Insert unique names into hash table.  The MN10300 instruction set
      has many identical opcode names that have different opcodes based
@@ -924,7 +924,7 @@ md_begin (void)
       if (strcmp (prev_name, op->name))
        {
          prev_name = (char *) op->name;
-         hash_insert (mn10300_hash, op->name, (char *) op);
+         str_hash_insert (mn10300_hash, op->name, op, 0);
        }
       op++;
     }
@@ -935,12 +935,15 @@ md_begin (void)
     as_warn (_("could not set architecture and machine"));
 
   current_machine = AM33_2;
-#else  
+#else
   if (!bfd_set_arch_mach (stdoutput, bfd_arch_mn10300, MN103))
     as_warn (_("could not set architecture and machine"));
 
   current_machine = MN103;
 #endif
+
+  /*  Set linkrelax here to avoid fixups in most sections.  */
+  linkrelax = 1;
 }
 
 static symbolS *GOT_symbol;
@@ -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;
 
@@ -1065,7 +1069,7 @@ mn10300_cons_fix_new (fragS *frag, int off, int size, expressionS *exp)
       as_bad (_("unsupported BFD relocation size %u"), size);
       fixup.reloc = BFD_RELOC_UNUSED;
     }
-    
+
   fix_new_exp (frag, off, size, &fixup.exp, 0, fixup.reloc);
 }
 
@@ -1243,7 +1247,7 @@ md_assemble (char *str)
     *s++ = '\0';
 
   /* Find the first opcode with the proper name.  */
-  opcode = (struct mn10300_opcode *) hash_find (mn10300_hash, str);
+  opcode = (struct mn10300_opcode *) str_hash_find (mn10300_hash, str);
   if (opcode == NULL)
     {
       as_bad (_("Unrecognized opcode: `%s'"), str);
@@ -1342,17 +1346,17 @@ md_assemble (char *str)
            }
          else if (operand->flags & MN10300_OPERAND_SP)
            {
-             char *start = input_line_pointer;
-             char c = get_symbol_end ();
+             char *start;
+             char c = get_symbol_name (&start);
 
              if (strcasecmp (start, "sp") != 0)
                {
-                 *input_line_pointer = c;
+                 (void) restore_line_pointer (c);
                  input_line_pointer = hold;
                  str = hold;
                  goto error;
                }
-             *input_line_pointer = c;
+             (void) restore_line_pointer (c);
              goto keep_going;
            }
          else if (operand->flags & MN10300_OPERAND_RREG)
@@ -1393,92 +1397,92 @@ md_assemble (char *str)
            }
          else if (operand->flags & MN10300_OPERAND_FPCR)
            {
-             char *start = input_line_pointer;
-             char c = get_symbol_end ();
+             char *start;
+             char c = get_symbol_name (&start);
 
              if (strcasecmp (start, "fpcr") != 0)
                {
-                 *input_line_pointer = c;
+                 (void) restore_line_pointer (c);
                  input_line_pointer = hold;
                  str = hold;
                  goto error;
                }
-             *input_line_pointer = c;
+             (void) restore_line_pointer (c);
              goto keep_going;
            }
          else if (operand->flags & MN10300_OPERAND_USP)
            {
-             char *start = input_line_pointer;
-             char c = get_symbol_end ();
+             char *start;
+             char c = get_symbol_name (&start);
 
              if (strcasecmp (start, "usp") != 0)
                {
-                 *input_line_pointer = c;
+                 (void) restore_line_pointer (c);
                  input_line_pointer = hold;
                  str = hold;
                  goto error;
                }
-             *input_line_pointer = c;
+             (void) restore_line_pointer (c);
              goto keep_going;
            }
          else if (operand->flags & MN10300_OPERAND_SSP)
            {
-             char *start = input_line_pointer;
-             char c = get_symbol_end ();
+             char *start;
+             char c = get_symbol_name (&start);
 
              if (strcasecmp (start, "ssp") != 0)
                {
-                 *input_line_pointer = c;
+                 (void) restore_line_pointer (c);
                  input_line_pointer = hold;
                  str = hold;
                  goto error;
                }
-             *input_line_pointer = c;
+             (void) restore_line_pointer (c);
              goto keep_going;
            }
          else if (operand->flags & MN10300_OPERAND_MSP)
            {
-             char *start = input_line_pointer;
-             char c = get_symbol_end ();
+             char *start;
+             char c = get_symbol_name (&start);
 
              if (strcasecmp (start, "msp") != 0)
                {
-                 *input_line_pointer = c;
+                 (void) restore_line_pointer (c);
                  input_line_pointer = hold;
                  str = hold;
                  goto error;
                }
-             *input_line_pointer = c;
+             (void) restore_line_pointer (c);
              goto keep_going;
            }
          else if (operand->flags & MN10300_OPERAND_PC)
            {
-             char *start = input_line_pointer;
-             char c = get_symbol_end ();
+             char *start;
+             char c = get_symbol_name (&start);
 
              if (strcasecmp (start, "pc") != 0)
                {
-                 *input_line_pointer = c;
+                 (void) restore_line_pointer (c);
                  input_line_pointer = hold;
                  str = hold;
                  goto error;
                }
-             *input_line_pointer = c;
+             (void) restore_line_pointer (c);
              goto keep_going;
            }
          else if (operand->flags & MN10300_OPERAND_EPSW)
            {
-             char *start = input_line_pointer;
-             char c = get_symbol_end ();
+             char *start;
+             char c = get_symbol_name (&start);
 
              if (strcasecmp (start, "epsw") != 0)
                {
-                 *input_line_pointer = c;
+                 (void) restore_line_pointer (c);
                  input_line_pointer = hold;
                  str = hold;
                  goto error;
                }
-             *input_line_pointer = c;
+             (void) restore_line_pointer (c);
              goto keep_going;
            }
          else if (operand->flags & MN10300_OPERAND_PLUS)
@@ -1494,32 +1498,32 @@ md_assemble (char *str)
            }
          else if (operand->flags & MN10300_OPERAND_PSW)
            {
-             char *start = input_line_pointer;
-             char c = get_symbol_end ();
+             char *start;
+             char c = get_symbol_name (&start);
 
              if (strcasecmp (start, "psw") != 0)
                {
-                 *input_line_pointer = c;
+                 (void) restore_line_pointer (c);
                  input_line_pointer = hold;
                  str = hold;
                  goto error;
                }
-             *input_line_pointer = c;
+             (void) restore_line_pointer (c);
              goto keep_going;
            }
          else if (operand->flags & MN10300_OPERAND_MDR)
            {
-             char *start = input_line_pointer;
-             char c = get_symbol_end ();
+             char *start;
+             char c = get_symbol_name (&start);
 
              if (strcasecmp (start, "mdr") != 0)
                {
-                 *input_line_pointer = c;
+                 (void) restore_line_pointer (c);
                  input_line_pointer = hold;
                  str = hold;
                  goto error;
                }
-             *input_line_pointer = c;
+             (void) restore_line_pointer (c);
              goto keep_going;
            }
          else if (operand->flags & MN10300_OPERAND_REG_LIST)
@@ -1550,57 +1554,56 @@ md_assemble (char *str)
                  if (*input_line_pointer == ',')
                    input_line_pointer++;
 
-                 start = input_line_pointer;
-                 c = get_symbol_end ();
+                 c = get_symbol_name (&start);
 
                  if (strcasecmp (start, "d2") == 0)
                    {
                      value |= 0x80;
-                     *input_line_pointer = c;
+                     (void) restore_line_pointer (c);
                    }
                  else if (strcasecmp (start, "d3") == 0)
                    {
                      value |= 0x40;
-                     *input_line_pointer = c;
+                     (void) restore_line_pointer (c);
                    }
                  else if (strcasecmp (start, "a2") == 0)
                    {
                      value |= 0x20;
-                     *input_line_pointer = c;
+                     (void) restore_line_pointer (c);
                    }
                  else if (strcasecmp (start, "a3") == 0)
                    {
                      value |= 0x10;
-                     *input_line_pointer = c;
+                     (void) restore_line_pointer (c);
                    }
                  else if (strcasecmp (start, "other") == 0)
                    {
                      value |= 0x08;
-                     *input_line_pointer = c;
+                     (void) restore_line_pointer (c);
                    }
                  else if (HAVE_AM33
                           && strcasecmp (start, "exreg0") == 0)
                    {
                      value |= 0x04;
-                     *input_line_pointer = c;
+                     (void) restore_line_pointer (c);
                    }
                  else if (HAVE_AM33
                           && strcasecmp (start, "exreg1") == 0)
                    {
                      value |= 0x02;
-                     *input_line_pointer = c;
+                     (void) restore_line_pointer (c);
                    }
                  else if (HAVE_AM33
                           && strcasecmp (start, "exother") == 0)
                    {
                      value |= 0x01;
-                     *input_line_pointer = c;
+                     (void) restore_line_pointer (c);
                    }
                  else if (HAVE_AM33
                           && strcasecmp (start, "all") == 0)
                    {
                      value |= 0xff;
-                     *input_line_pointer = c;
+                     (void) restore_line_pointer (c);
                    }
                  else
                    {
@@ -1756,7 +1759,7 @@ md_assemble (char *str)
              break;
            }
 
-keep_going:
+       keep_going:
          str = input_line_pointer;
          input_line_pointer = hold;
 
@@ -1862,7 +1865,7 @@ keep_going:
         as the size of a pointer, so we need a union to convert
         the opindex field of the fr_cgen structure into a char *
         so that it can be stored in the frag.  We do not have
-        to worry about loosing accuracy as we are not going to
+        to worry about losing accuracy as we are not going to
         be even close to the 32bit limit of the int.  */
       union
       {
@@ -2061,6 +2064,12 @@ keep_going:
              && 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;
@@ -2159,7 +2168,7 @@ tc_gen_reloc (asection *seg ATTRIBUTE_UNUSED, fixS *fixp)
   static arelent * relocs[MAX_RELOC_EXPANSION + 1];
   arelent *reloc;
 
-  reloc = xmalloc (sizeof (arelent));
+  reloc = XNEW (arelent);
 
   reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
   if (reloc->howto == NULL)
@@ -2189,15 +2198,13 @@ 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,
         even local symbols defined in the same section.  */
       if (ssec != absolute_section || asec != absolute_section)
        {
-         arelent * reloc2 = xmalloc (sizeof * reloc);
+         arelent * reloc2 = XNEW (arelent);
 
          relocs[0] = reloc2;
          relocs[1] = reloc;
@@ -2205,15 +2212,20 @@ tc_gen_reloc (asection *seg ATTRIBUTE_UNUSED, fixS *fixp)
          reloc2->address = reloc->address;
          reloc2->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_MN10300_SYM_DIFF);
          reloc2->addend = - S_GET_VALUE (fixp->fx_subsy);
-         reloc2->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
+         reloc2->sym_ptr_ptr = XNEW (asymbol *);
          *reloc2->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_subsy);
 
-         reloc->addend = fixp->fx_offset; 
+         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 = XNEW (asymbol *);
+             *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
+           }
 
          fixp->fx_pcrel = 0;
          fixp->fx_done = 1;
@@ -2250,15 +2262,13 @@ 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;
        }
     }
   else
     {
-      reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
+      reloc->sym_ptr_ptr = XNEW (asymbol *);
       *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
       reloc->addend = fixp->fx_offset;
     }
@@ -2272,7 +2282,7 @@ static inline bfd_boolean
 has_known_symbol_location (fragS * fragp, asection * sec)
 {
   symbolS * sym = fragp->fr_symbol;
-  
+
   return sym != NULL
     && S_IS_DEFINED (sym)
     && ! S_IS_WEAK (sym)
@@ -2373,7 +2383,7 @@ md_apply_fix (fixS * fixP, valueT * valP, segT seg)
     case BFD_RELOC_MN10300_ALIGN:
       fixP->fx_done = 1;
       return;
-      
+
     case BFD_RELOC_NONE:
     default:
       as_bad_where (fixP->fx_file, fixP->fx_line,
@@ -2412,7 +2422,7 @@ mn10300_fix_adjustable (struct fix *fixp)
 
   /* Likewise, do not adjust symbols that won't be merged, or debug
      symbols, because they too break relaxation.  We do want to adjust
-     other mergable symbols, like .rodata, because code relaxations
+     other mergeable symbols, like .rodata, because code relaxations
      need section-relative symbols to properly relax them.  */
   if (! (S_GET_SEGMENT (fixp->fx_addsy)->flags & SEC_MERGE))
     return FALSE;
@@ -2433,7 +2443,7 @@ set_arch_mach (int mach)
 }
 
 static inline char *
-mn10300_end_of_match (char *cont, char *what)
+mn10300_end_of_match (char *cont, const char *what)
 {
   int len = strlen (what);
 
@@ -2442,7 +2452,7 @@ mn10300_end_of_match (char *cont, char *what)
     return cont + len;
 
   return NULL;
-}  
+}
 
 int
 mn10300_parse_name (char const *name,
@@ -2489,7 +2499,7 @@ mn10300_parse_name (char const *name,
     }
 
   exprP->X_add_symbol = symbol_find_or_make (name);
-  
+
   if (*nextcharP != '@')
     goto no_suffix;
   else if ((next_end = mn10300_end_of_match (next + 1, "GOTOFF")))
@@ -2498,6 +2508,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;
 
@@ -2594,9 +2616,9 @@ mn10300_handle_align (fragS *frag)
       && now_seg != bss_section
       /* Do not create relocs for the merging sections - such
         relocs will prevent the contents from being merged.  */
-      && (bfd_get_section_flags (now_seg->owner, now_seg) & SEC_MERGE) == 0)
+      && (bfd_section_flags (now_seg) & SEC_MERGE) == 0)
     /* Create a new fixup to record the alignment request.  The symbol is
-       irrelevent but must be present so we use the absolute section symbol.
+       irrelevant but must be present so we use the absolute section symbol.
        The offset from the symbol is used to record the power-of-two alignment
        value.  The size is set to 0 because the frag may already be aligned,
        thus causing cvt_frag_to_fill to reduce the size of the frag to zero.  */