Enable support for the AArch64 dot-prod instruction in the Cortex A55 and A75 cpus.
[deliverable/binutils-gdb.git] / bfd / elf32-m32c.c
index 69e617f54b8fe92decd88bd8049a8296a997f1f2..2cb28b21d78d9718a2a7128ed5df8dfc99c7b7c3 100644 (file)
@@ -1,12 +1,11 @@
 /* M16C/M32C specific support for 32-bit ELF.
 /* M16C/M32C specific support for 32-bit ELF.
-   Copyright (C) 2005, 2006
-   Free Software Foundation, Inc.
+   Copyright (C) 2005-2017 Free Software Foundation, Inc.
 
    This file is part of BFD, the Binary File Descriptor library.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
 
    This file is part of BFD, the Binary File Descriptor library.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
@@ -18,8 +17,8 @@
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
-#include "bfd.h"
 #include "sysdep.h"
 #include "sysdep.h"
+#include "bfd.h"
 #include "libbfd.h"
 #include "elf-bfd.h"
 #include "elf/m32c.h"
 #include "libbfd.h"
 #include "elf-bfd.h"
 #include "elf/m32c.h"
 /* Forward declarations.  */
 static reloc_howto_type * m32c_reloc_type_lookup
   (bfd *, bfd_reloc_code_real_type);
 /* Forward declarations.  */
 static reloc_howto_type * m32c_reloc_type_lookup
   (bfd *, bfd_reloc_code_real_type);
-static void m32c_info_to_howto_rela 
+static void m32c_info_to_howto_rela
   (bfd *, arelent *, Elf_Internal_Rela *);
   (bfd *, arelent *, Elf_Internal_Rela *);
-static bfd_boolean m32c_elf_relocate_section 
+static bfd_boolean m32c_elf_relocate_section
   (bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, Elf_Internal_Rela *, Elf_Internal_Sym *, asection **);
   (bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, Elf_Internal_Rela *, Elf_Internal_Sym *, asection **);
-static bfd_boolean m32c_elf_gc_sweep_hook
-  (bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *);
-static asection * m32c_elf_gc_mark_hook
-  (asection *, struct bfd_link_info *, Elf_Internal_Rela *, struct elf_link_hash_entry *, Elf_Internal_Sym *);
 static bfd_boolean m32c_elf_check_relocs
   (bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *);
 static bfd_boolean m32c_elf_relax_delete_bytes (bfd *, asection *, bfd_vma, int);
 static bfd_boolean m32c_elf_check_relocs
   (bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *);
 static bfd_boolean m32c_elf_relax_delete_bytes (bfd *, asection *, bfd_vma, int);
@@ -45,6 +40,8 @@ void dump_symtab (bfd *, void *, void *);
 #endif
 static bfd_boolean m32c_elf_relax_section
 (bfd *abfd, asection *sec, struct bfd_link_info *link_info, bfd_boolean *again);
 #endif
 static bfd_boolean m32c_elf_relax_section
 (bfd *abfd, asection *sec, struct bfd_link_info *link_info, bfd_boolean *again);
+static bfd_reloc_status_type m32c_apply_reloc_24
+  (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
 
 
 static reloc_howto_type m32c_elf_howto_table [] =
 
 
 static reloc_howto_type m32c_elf_howto_table [] =
@@ -52,11 +49,11 @@ static reloc_howto_type m32c_elf_howto_table [] =
   /* This reloc does nothing.  */
   HOWTO (R_M32C_NONE,          /* type */
         0,                     /* rightshift */
   /* This reloc does nothing.  */
   HOWTO (R_M32C_NONE,          /* type */
         0,                     /* rightshift */
-        0,                     /* size (0 = byte, 1 = short, 2 = long) */
-        32,                    /* bitsize */
+        3,                     /* size (0 = byte, 1 = short, 2 = long) */
+        0,                     /* bitsize */
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
-        complain_overflow_bitfield, /* complain_on_overflow */
+        complain_overflow_dont, /* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_M32C_NONE",         /* name */
         FALSE,                 /* partial_inplace */
         bfd_elf_generic_reloc, /* special_function */
         "R_M32C_NONE",         /* name */
         FALSE,                 /* partial_inplace */
@@ -64,13 +61,16 @@ static reloc_howto_type m32c_elf_howto_table [] =
         0,                     /* dst_mask */
         FALSE),                /* pcrel_offset */
 
         0,                     /* dst_mask */
         FALSE),                /* pcrel_offset */
 
+  /* GCC intentionally overflows these next two in order to work
+     around limitations in the addressing modes, so don't complain
+     about overflow.  */
   HOWTO (R_M32C_16,            /* type */
         0,                     /* rightshift */
         1,                     /* size (0 = byte, 1 = short, 2 = long) */
         16,                    /* bitsize */
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
   HOWTO (R_M32C_16,            /* type */
         0,                     /* rightshift */
         1,                     /* size (0 = byte, 1 = short, 2 = long) */
         16,                    /* bitsize */
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
-        complain_overflow_bitfield, /* complain_on_overflow */
+        complain_overflow_dont, /* complain_on_overflow */
         bfd_elf_generic_reloc, /* special_function */
         "R_M32C_16",           /* name */
         FALSE,                 /* partial_inplace */
         bfd_elf_generic_reloc, /* special_function */
         "R_M32C_16",           /* name */
         FALSE,                 /* partial_inplace */
@@ -84,8 +84,8 @@ static reloc_howto_type m32c_elf_howto_table [] =
         24,                    /* bitsize */
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         24,                    /* bitsize */
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
-        complain_overflow_bitfield, /* complain_on_overflow */
-        bfd_elf_generic_reloc, /* special_function */
+        complain_overflow_dont, /* complain_on_overflow */
+        m32c_apply_reloc_24,   /* special_function */
         "R_M32C_24",           /* name */
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
         "R_M32C_24",           /* name */
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
@@ -266,10 +266,25 @@ m32c_reloc_type_lookup
 {
   unsigned int i;
 
 {
   unsigned int i;
 
-  for (i = ARRAY_SIZE (m32c_reloc_map); --i;)
+  for (i = ARRAY_SIZE (m32c_reloc_map); i--;)
     if (m32c_reloc_map [i].bfd_reloc_val == code)
       return & m32c_elf_howto_table [m32c_reloc_map[i].m32c_reloc_val];
     if (m32c_reloc_map [i].bfd_reloc_val == code)
       return & m32c_elf_howto_table [m32c_reloc_map[i].m32c_reloc_val];
-  
+
+  return NULL;
+}
+
+static reloc_howto_type *
+m32c_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, const char *r_name)
+{
+  unsigned int i;
+
+  for (i = 0;
+       i < sizeof (m32c_elf_howto_table) / sizeof (m32c_elf_howto_table[0]);
+       i++)
+    if (m32c_elf_howto_table[i].name != NULL
+       && strcasecmp (m32c_elf_howto_table[i].name, r_name) == 0)
+      return &m32c_elf_howto_table[i];
+
   return NULL;
 }
 
   return NULL;
 }
 
@@ -284,12 +299,59 @@ m32c_info_to_howto_rela
   unsigned int r_type;
 
   r_type = ELF32_R_TYPE (dst->r_info);
   unsigned int r_type;
 
   r_type = ELF32_R_TYPE (dst->r_info);
-  BFD_ASSERT (r_type < (unsigned int) R_M32C_max);
+  if (r_type >= (unsigned int) R_M32C_max)
+    {
+      /* xgettext:c-format */
+      _bfd_error_handler (_("%B: invalid M32C reloc number: %d"), abfd, r_type);
+      r_type = 0;
+    }
   cache_ptr->howto = & m32c_elf_howto_table [r_type];
 }
 
 \f
 
   cache_ptr->howto = & m32c_elf_howto_table [r_type];
 }
 
 \f
 
+/* Apply R_M32C_24 relocations.  We have to do this because it's not a
+   power-of-two size, and the generic code may think it overruns the
+   section if it's right at the end.
+
+   Must return something other than bfd_reloc_continue to avoid the
+   above problem.  Typical return values include bfd_reloc_ok or
+   bfd_reloc_overflow.
+*/
+
+static bfd_reloc_status_type m32c_apply_reloc_24 (bfd *abfd ATTRIBUTE_UNUSED,
+                                                 arelent *reloc_entry,
+                                                 asymbol *symbol,
+                                                 void *vdata_start ATTRIBUTE_UNUSED,
+                                                 asection *input_section,
+                                                 bfd *ibfd ATTRIBUTE_UNUSED,
+                                                 char **error_msg ATTRIBUTE_UNUSED)
+{
+  bfd_vma relocation;
+  bfd_reloc_status_type s;
+
+  s = bfd_elf_generic_reloc (abfd, reloc_entry, symbol,
+                            vdata_start,
+                            input_section, ibfd, error_msg);
+  if (s != bfd_reloc_continue)
+    return s;
+
+  /* Get symbol value.  (Common symbols are special.)  */
+  if (bfd_is_com_section (symbol->section))
+    relocation = 0;
+  else
+    relocation = symbol->value;
+
+  relocation += symbol->section->output_offset;
+
+  /* Add in supplied addend.  */
+  relocation += reloc_entry->addend;
+
+  reloc_entry->addend = relocation;
+  reloc_entry->address += input_section->output_offset;
+  return bfd_reloc_ok;
+}
+
 /* Relocate an M32C ELF section.
    There is some attempt to make this function usable for many architectures,
    both USE_REL and USE_RELA ['twould be nice if such a critter existed],
 /* Relocate an M32C ELF section.
    There is some attempt to make this function usable for many architectures,
    both USE_REL and USE_RELA ['twould be nice if such a critter existed],
@@ -338,17 +400,13 @@ m32c_elf_relocate_section
   struct elf_link_hash_entry ** sym_hashes;
   Elf_Internal_Rela *           rel;
   Elf_Internal_Rela *           relend;
   struct elf_link_hash_entry ** sym_hashes;
   Elf_Internal_Rela *           rel;
   Elf_Internal_Rela *           relend;
-  bfd *dynobj;
   asection *splt;
 
   symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
   sym_hashes = elf_sym_hashes (input_bfd);
   relend     = relocs + input_section->reloc_count;
 
   asection *splt;
 
   symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
   sym_hashes = elf_sym_hashes (input_bfd);
   relend     = relocs + input_section->reloc_count;
 
-  dynobj = elf_hash_table (info)->dynobj;
-  splt = NULL;
-  if (dynobj != NULL)
-    splt = bfd_get_section_by_name (dynobj, ".plt");
+  splt = elf_hash_table (info)->splt;
 
   for (rel = relocs; rel < relend; rel ++)
     {
 
   for (rel = relocs; rel < relend; rel ++)
     {
@@ -361,7 +419,7 @@ m32c_elf_relocate_section
       bfd_reloc_status_type        r;
       const char *                 name = NULL;
       int                          r_type;
       bfd_reloc_status_type        r;
       const char *                 name = NULL;
       int                          r_type;
-      
+
       r_type = ELF32_R_TYPE (rel->r_info);
 
       /* These are only used for relaxing; we don't actually relocate
       r_type = ELF32_R_TYPE (rel->r_info);
 
       /* These are only used for relaxing; we don't actually relocate
@@ -370,34 +428,14 @@ m32c_elf_relocate_section
          || r_type == R_M32C_RL_1ADDR
          || r_type == R_M32C_RL_2ADDR)
        continue;
          || r_type == R_M32C_RL_1ADDR
          || r_type == R_M32C_RL_2ADDR)
        continue;
-      
-      r_symndx = ELF32_R_SYM (rel->r_info);
 
 
-      if (info->relocatable)
-       {
-         /* This is a relocatable link.  We don't have to change
-             anything, unless the reloc is against a section symbol,
-             in which case we have to adjust according to where the
-             section symbol winds up in the output section.  */
-         if (r_symndx < symtab_hdr->sh_info)
-           {
-             sym = local_syms + r_symndx;
-             
-             if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
-               {
-                 sec = local_sections [r_symndx];
-                 rel->r_addend += sec->output_offset + sym->st_value;
-               }
-           }
-
-         continue;
-       }
+      r_symndx = ELF32_R_SYM (rel->r_info);
 
 
-      /* This is a final link.  */
       howto  = m32c_elf_howto_table + ELF32_R_TYPE (rel->r_info);
       h      = NULL;
       sym    = NULL;
       sec    = NULL;
       howto  = m32c_elf_howto_table + ELF32_R_TYPE (rel->r_info);
       h      = NULL;
       sym    = NULL;
       sec    = NULL;
+      relocation = 0;
 
       if (r_symndx < symtab_hdr->sh_info)
        {
 
       if (r_symndx < symtab_hdr->sh_info)
        {
@@ -406,7 +444,7 @@ m32c_elf_relocate_section
          relocation = (sec->output_section->vma
                        + sec->output_offset
                        + sym->st_value);
          relocation = (sec->output_section->vma
                        + sec->output_offset
                        + sym->st_value);
-         
+
          name = bfd_elf_string_from_elf_section
            (input_bfd, symtab_hdr->sh_link, sym->st_name);
          name = (sym->st_name == 0) ? bfd_section_name (input_bfd, sec) : name;
          name = bfd_elf_string_from_elf_section
            (input_bfd, symtab_hdr->sh_link, sym->st_name);
          name = (sym->st_name == 0) ? bfd_section_name (input_bfd, sec) : name;
@@ -414,13 +452,18 @@ m32c_elf_relocate_section
       else
        {
          h = sym_hashes [r_symndx - symtab_hdr->sh_info];
       else
        {
          h = sym_hashes [r_symndx - symtab_hdr->sh_info];
-         
+
+         if (info->wrap_hash != NULL
+             && (input_section->flags & SEC_DEBUGGING) != 0)
+           h = ((struct elf_link_hash_entry *)
+                unwrap_hash_lookup (info, input_bfd, &h->root));
+
          while (h->root.type == bfd_link_hash_indirect
                 || h->root.type == bfd_link_hash_warning)
            h = (struct elf_link_hash_entry *) h->root.u.i.link;
 
          name = h->root.root.string;
          while (h->root.type == bfd_link_hash_indirect
                 || h->root.type == bfd_link_hash_warning)
            h = (struct elf_link_hash_entry *) h->root.u.i.link;
 
          name = h->root.root.string;
-         
+
          if (h->root.type == bfd_link_hash_defined
              || h->root.type == bfd_link_hash_defweak)
            {
          if (h->root.type == bfd_link_hash_defined
              || h->root.type == bfd_link_hash_defweak)
            {
@@ -430,17 +473,26 @@ m32c_elf_relocate_section
                            + sec->output_offset);
            }
          else if (h->root.type == bfd_link_hash_undefweak)
                            + sec->output_offset);
            }
          else if (h->root.type == bfd_link_hash_undefweak)
-           {
-             relocation = 0;
-           }
-         else
-           {
-             if (! ((*info->callbacks->undefined_symbol)
-                    (info, h->root.root.string, input_bfd,
-                     input_section, rel->r_offset, TRUE)))
-               return FALSE;
-             relocation = 0;
-           }
+           ;
+         else if (!bfd_link_relocatable (info))
+           (*info->callbacks->undefined_symbol) (info, h->root.root.string,
+                                                 input_bfd, input_section,
+                                                 rel->r_offset, TRUE);
+       }
+
+      if (sec != NULL && discarded_section (sec))
+       RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+                                        rel, 1, relend, howto, 0, contents);
+
+      if (bfd_link_relocatable (info))
+       {
+         /* This is a relocatable link.  We don't have to change
+             anything, unless the reloc is against a section symbol,
+             in which case we have to adjust according to where the
+             section symbol winds up in the output section.  */
+         if (sym != NULL && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
+           rel->r_addend += sec->output_offset;
+         continue;
        }
 
       switch (ELF32_R_TYPE (rel->r_info))
        }
 
       switch (ELF32_R_TYPE (rel->r_info))
@@ -521,9 +573,32 @@ m32c_elf_relocate_section
        printf ("\n");
       }
 #endif
        printf ("\n");
       }
 #endif
-      r = _bfd_final_link_relocate (howto, input_bfd, input_section,
-                                    contents, rel->r_offset, relocation,
-                                    rel->r_addend);
+      switch (ELF32_R_TYPE(rel->r_info))
+       {
+       case R_M32C_24:
+         /* Like m32c_apply_reloc_24, we must handle this one separately.  */
+         relocation += rel->r_addend;
+
+         /* Sanity check the address.  */
+         if (rel->r_offset + 3
+             > bfd_get_section_limit_octets (input_bfd, input_section))
+           r = bfd_reloc_outofrange;
+         else
+           {
+             bfd_put_8 (input_bfd, relocation & 0xff, contents + rel->r_offset);
+             bfd_put_8 (input_bfd, (relocation >> 8) & 0xff, contents + rel->r_offset + 1);
+             bfd_put_8 (input_bfd, (relocation >> 16) & 0xff, contents + rel->r_offset + 2);
+             r = bfd_reloc_ok;
+           }
+
+         break;
+
+       default:
+         r = _bfd_final_link_relocate (howto, input_bfd, input_section,
+                                       contents, rel->r_offset, relocation,
+                                       rel->r_addend);
+         break;
+       }
 
       if (r != bfd_reloc_ok)
        {
 
       if (r != bfd_reloc_ok)
        {
@@ -532,17 +607,16 @@ m32c_elf_relocate_section
          switch (r)
            {
            case bfd_reloc_overflow:
          switch (r)
            {
            case bfd_reloc_overflow:
-             r = info->callbacks->reloc_overflow
+             (*info->callbacks->reloc_overflow)
                (info, (h ? &h->root : NULL), name, howto->name, (bfd_vma) 0,
                 input_bfd, input_section, rel->r_offset);
              break;
                (info, (h ? &h->root : NULL), name, howto->name, (bfd_vma) 0,
                 input_bfd, input_section, rel->r_offset);
              break;
-             
+
            case bfd_reloc_undefined:
            case bfd_reloc_undefined:
-             r = info->callbacks->undefined_symbol
-               (info, name, input_bfd, input_section, rel->r_offset,
-                TRUE);
+             (*info->callbacks->undefined_symbol)
+               (info, name, input_bfd, input_section, rel->r_offset, TRUE);
              break;
              break;
-             
+
            case bfd_reloc_outofrange:
              msg = _("internal error: out of range error");
              break;
            case bfd_reloc_outofrange:
              msg = _("internal error: out of range error");
              break;
@@ -561,76 +635,17 @@ m32c_elf_relocate_section
            }
 
          if (msg)
            }
 
          if (msg)
-           r = info->callbacks->warning
-             (info, msg, name, input_bfd, input_section, rel->r_offset);
-
-         if (! r)
-           return FALSE;
+           (*info->callbacks->warning) (info, msg, name, input_bfd,
+                                        input_section, rel->r_offset);
        }
     }
 
   return TRUE;
 }
 \f
        }
     }
 
   return TRUE;
 }
 \f
-/* Return the section that should be marked against GC for a given
-   relocation.  */
-
-static asection *
-m32c_elf_gc_mark_hook
-    (asection *                   sec,
-     struct bfd_link_info *       info ATTRIBUTE_UNUSED,
-     Elf_Internal_Rela *          rel,
-     struct elf_link_hash_entry * h,
-     Elf_Internal_Sym *           sym)
-{
-  if (h != NULL)
-    {
-      switch (ELF32_R_TYPE (rel->r_info))
-       {
-       default:
-         switch (h->root.type)
-           {
-           case bfd_link_hash_defined:
-           case bfd_link_hash_defweak:
-             return h->root.u.def.section;
-
-           case bfd_link_hash_common:
-             return h->root.u.c.p->section;
-
-           default:
-             break;
-           }
-       }
-    }
-  else
-    {
-      if (!(elf_bad_symtab (sec->owner)
-           && ELF_ST_BIND (sym->st_info) != STB_LOCAL)
-         && ! ((sym->st_shndx <= 0 || sym->st_shndx >= SHN_LORESERVE)
-               && sym->st_shndx != SHN_COMMON))
-       {
-         return bfd_section_from_elf_index (sec->owner, sym->st_shndx);
-       }
-    }
-
-  return NULL;
-}
-
-/* Update the got entry reference counts for the section being removed.  */
-
-static bfd_boolean
-m32c_elf_gc_sweep_hook
-    (bfd *                     abfd ATTRIBUTE_UNUSED,
-     struct bfd_link_info *    info ATTRIBUTE_UNUSED,
-     asection *                sec ATTRIBUTE_UNUSED,
-     const Elf_Internal_Rela * relocs ATTRIBUTE_UNUSED)
-{
-  return TRUE;
-}
-
 /* We support 16-bit pointers to code above 64k by generating a thunk
    below 64k containing a JMP instruction to the final address.  */
 /* We support 16-bit pointers to code above 64k by generating a thunk
    below 64k containing a JMP instruction to the final address.  */
+
 static bfd_boolean
 m32c_elf_check_relocs
     (bfd *                     abfd,
 static bfd_boolean
 m32c_elf_check_relocs
     (bfd *                     abfd,
@@ -640,33 +655,28 @@ m32c_elf_check_relocs
 {
   Elf_Internal_Shdr *           symtab_hdr;
   struct elf_link_hash_entry ** sym_hashes;
 {
   Elf_Internal_Shdr *           symtab_hdr;
   struct elf_link_hash_entry ** sym_hashes;
-  struct elf_link_hash_entry ** sym_hashes_end;
   const Elf_Internal_Rela *     rel;
   const Elf_Internal_Rela *     rel_end;
   bfd_vma *local_plt_offsets;
   asection *splt;
   bfd *dynobj;
   const Elf_Internal_Rela *     rel;
   const Elf_Internal_Rela *     rel_end;
   bfd_vma *local_plt_offsets;
   asection *splt;
   bfd *dynobj;
-  if (info->relocatable)
+
+  if (bfd_link_relocatable (info))
     return TRUE;
     return TRUE;
+
   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
   sym_hashes = elf_sym_hashes (abfd);
   local_plt_offsets = elf_local_got_offsets (abfd);
   splt = NULL;
   dynobj = elf_hash_table(info)->dynobj;
 
   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
   sym_hashes = elf_sym_hashes (abfd);
   local_plt_offsets = elf_local_got_offsets (abfd);
   splt = NULL;
   dynobj = elf_hash_table(info)->dynobj;
 
-  sym_hashes_end = sym_hashes + symtab_hdr->sh_size/sizeof (Elf32_External_Sym);
-  if (!elf_bad_symtab (abfd))
-    sym_hashes_end -= symtab_hdr->sh_info;
   rel_end = relocs + sec->reloc_count;
   for (rel = relocs; rel < rel_end; rel++)
     {
       struct elf_link_hash_entry *h;
       unsigned long r_symndx;
       bfd_vma *offset;
   rel_end = relocs + sec->reloc_count;
   for (rel = relocs; rel < rel_end; rel++)
     {
       struct elf_link_hash_entry *h;
       unsigned long r_symndx;
       bfd_vma *offset;
+
       r_symndx = ELF32_R_SYM (rel->r_info);
       if (r_symndx < symtab_hdr->sh_info)
         h = NULL;
       r_symndx = ELF32_R_SYM (rel->r_info);
       if (r_symndx < symtab_hdr->sh_info)
         h = NULL;
@@ -676,8 +686,12 @@ m32c_elf_check_relocs
          while (h->root.type == bfd_link_hash_indirect
                 || h->root.type == bfd_link_hash_warning)
            h = (struct elf_link_hash_entry *) h->root.u.i.link;
          while (h->root.type == bfd_link_hash_indirect
                 || h->root.type == bfd_link_hash_warning)
            h = (struct elf_link_hash_entry *) h->root.u.i.link;
+
+         /* PR15323, ref flags aren't set for references in the same
+            object.  */
+         h->root.non_ir_ref_regular = 1;
        }
        }
+
       switch (ELF32_R_TYPE (rel->r_info))
         {
          /* This relocation describes a 16-bit pointer to a function.
       switch (ELF32_R_TYPE (rel->r_info))
         {
          /* This relocation describes a 16-bit pointer to a function.
@@ -686,19 +700,18 @@ m32c_elf_check_relocs
        case R_M32C_16:
          if (dynobj == NULL)
            elf_hash_table (info)->dynobj = dynobj = abfd;
        case R_M32C_16:
          if (dynobj == NULL)
            elf_hash_table (info)->dynobj = dynobj = abfd;
+         splt = elf_hash_table (info)->splt;
          if (splt == NULL)
            {
          if (splt == NULL)
            {
-             splt = bfd_get_section_by_name (dynobj, ".plt");
-             if (splt == NULL)
-               {
-                 flagword flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
-                                   | SEC_IN_MEMORY | SEC_LINKER_CREATED
-                                   | SEC_READONLY | SEC_CODE);
-                 splt = bfd_make_section_with_flags (dynobj, ".plt", flags);
-                 if (splt == NULL
-                     || ! bfd_set_section_alignment (dynobj, splt, 1))
-                   return FALSE;
-               }
+             flagword flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
+                               | SEC_IN_MEMORY | SEC_LINKER_CREATED
+                               | SEC_READONLY | SEC_CODE);
+             splt = bfd_make_section_anyway_with_flags (dynobj, ".plt",
+                                                        flags);
+             elf_hash_table (info)->splt = splt;
+             if (splt == NULL
+                 || ! bfd_set_section_alignment (dynobj, splt, 1))
+               return FALSE;
            }
 
          if (h != NULL)
            }
 
          if (h != NULL)
@@ -730,7 +743,7 @@ m32c_elf_check_relocs
          break;
         }
     }
          break;
         }
     }
+
   return TRUE;
 }
 
   return TRUE;
 }
 
@@ -740,14 +753,13 @@ static bfd_boolean
 m32c_elf_finish_dynamic_sections (bfd *abfd ATTRIBUTE_UNUSED,
                                   struct bfd_link_info *info)
 {
 m32c_elf_finish_dynamic_sections (bfd *abfd ATTRIBUTE_UNUSED,
                                   struct bfd_link_info *info)
 {
-  bfd *dynobj;
-  asection *splt;
+  bfd *dynobj = elf_hash_table (info)->dynobj;
+  asection *splt = elf_hash_table (info)->splt;
 
   /* As an extra sanity check, verify that all plt entries have
      been filled in.  */
 
 
   /* As an extra sanity check, verify that all plt entries have
      been filled in.  */
 
-  if ((dynobj = elf_hash_table (info)->dynobj) != NULL
-      && (splt = bfd_get_section_by_name (dynobj, ".plt")) != NULL)
+  if (dynobj != NULL && splt != NULL)
     {
       bfd_byte *contents = splt->contents;
       unsigned int i, size = splt->size;
     {
       bfd_byte *contents = splt->contents;
       unsigned int i, size = splt->size;
@@ -768,14 +780,14 @@ m32c_elf_always_size_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
   bfd *dynobj;
   asection *splt;
 
   bfd *dynobj;
   asection *splt;
 
-  if (info->relocatable)
+  if (bfd_link_relocatable (info))
     return TRUE;
 
   dynobj = elf_hash_table (info)->dynobj;
   if (dynobj == NULL)
     return TRUE;
 
     return TRUE;
 
   dynobj = elf_hash_table (info)->dynobj;
   if (dynobj == NULL)
     return TRUE;
 
-  splt = bfd_get_section_by_name (dynobj, ".plt");
+  splt = elf_hash_table (info)->splt;
   BFD_ASSERT (splt != NULL);
 
   splt->contents = (bfd_byte *) bfd_zalloc (dynobj, splt->size);
   BFD_ASSERT (splt != NULL);
 
   splt->contents = (bfd_byte *) bfd_zalloc (dynobj, splt->size);
@@ -799,8 +811,9 @@ m32c_elf_set_private_flags (bfd *abfd, flagword flags)
    object file when linking.  */
 
 static bfd_boolean
    object file when linking.  */
 
 static bfd_boolean
-m32c_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
+m32c_elf_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
 {
 {
+  bfd *obfd = info->output_bfd;
   flagword old_flags, old_partial;
   flagword new_flags, new_partial;
   bfd_boolean error = FALSE;
   flagword old_flags, old_partial;
   flagword new_flags, new_partial;
   bfd_boolean error = FALSE;
@@ -812,9 +825,10 @@ m32c_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
   old_flags = elf_elfheader (obfd)->e_flags;
 
 #ifdef DEBUG
   old_flags = elf_elfheader (obfd)->e_flags;
 
 #ifdef DEBUG
-  (*_bfd_error_handler) ("old_flags = 0x%.8lx, new_flags = 0x%.8lx, init = %s, filename = %s",
-                        old_flags, new_flags, elf_flags_init (obfd) ? "yes" : "no",
-                        bfd_get_filename (ibfd));
+  _bfd_error_handler
+    ("old_flags = 0x%.8x, new_flags = 0x%.8x, init = %s, filename = %s",
+     old_flags, new_flags, elf_flags_init (obfd) ? "yes" : "no",
+     bfd_get_filename (ibfd));
 #endif
 
   if (!elf_flags_init (obfd))
 #endif
 
   if (!elf_flags_init (obfd))
@@ -853,14 +867,15 @@ m32c_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
            case EF_M32C_CPU_M32C:  strcat (old_opt, " -m32c");  break;
            }
        }
            case EF_M32C_CPU_M32C:  strcat (old_opt, " -m32c");  break;
            }
        }
-      
+
       /* Print out any mismatches from above.  */
       if (new_opt[0])
        {
          error = TRUE;
       /* Print out any mismatches from above.  */
       if (new_opt[0])
        {
          error = TRUE;
-         (*_bfd_error_handler)
-           (_("%s: compiled with %s and linked with modules compiled with %s"),
-            bfd_get_filename (ibfd), new_opt, old_opt);
+         _bfd_error_handler
+           /* xgettext:c-format */
+           (_("%B: compiled with %s and linked with modules compiled with %s"),
+            ibfd, new_opt, old_opt);
        }
 
       new_flags &= ~ EF_M32C_ALL_FLAGS;
        }
 
       new_flags &= ~ EF_M32C_ALL_FLAGS;
@@ -870,9 +885,11 @@ m32c_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
       if (new_flags != old_flags)
        {
          error = TRUE;
       if (new_flags != old_flags)
        {
          error = TRUE;
-         (*_bfd_error_handler)
-           (_("%s: uses different e_flags (0x%lx) fields than previous modules (0x%lx)"),
-            bfd_get_filename (ibfd), (long)new_flags, (long)old_flags);
+         _bfd_error_handler
+           /* xgettext:c-format */
+           (_("%B: uses different e_flags (%#x) fields"
+              " than previous modules (%#x)"),
+            ibfd, new_flags, old_flags);
        }
     }
 
        }
     }
 
@@ -884,7 +901,7 @@ m32c_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
 
 \f
 static bfd_boolean
 
 \f
 static bfd_boolean
-m32c_elf_print_private_bfd_data (bfd *abfd, PTR ptr)
+m32c_elf_print_private_bfd_data (bfd *abfd, void *ptr)
 {
   FILE *file = (FILE *) ptr;
   flagword flags;
 {
   FILE *file = (FILE *) ptr;
   flagword flags;
@@ -895,7 +912,7 @@ m32c_elf_print_private_bfd_data (bfd *abfd, PTR ptr)
   _bfd_elf_print_private_bfd_data (abfd, ptr);
 
   flags = elf_elfheader (abfd)->e_flags;
   _bfd_elf_print_private_bfd_data (abfd, ptr);
 
   flags = elf_elfheader (abfd)->e_flags;
-  fprintf (file, _("private flags = 0x%lx:"), (long)flags);
+  fprintf (file, _("private flags = 0x%lx:"), (unsigned long) flags);
 
   switch (flags & EF_M32C_CPU_MASK)
     {
 
   switch (flags & EF_M32C_CPU_MASK)
     {
@@ -956,7 +973,7 @@ dump_symtab (bfd * abfd, void *internal_syms, void *external_syms)
       external_syms = bfd_malloc (1000);
       free_external = 1;
     }
       external_syms = bfd_malloc (1000);
       free_external = 1;
     }
-  
+
   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
   locsymcount = symtab_hdr->sh_size / get_elf_backend_data(abfd)->s->sizeof_sym;
   if (free_internal)
   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
   locsymcount = symtab_hdr->sh_size / get_elf_backend_data(abfd)->s->sizeof_sym;
   if (free_internal)
@@ -971,37 +988,83 @@ dump_symtab (bfd * abfd, void *internal_syms, void *external_syms)
     {
       switch (ELF_ST_TYPE (isym->st_info))
        {
     {
       switch (ELF_ST_TYPE (isym->st_info))
        {
-       case STT_FUNC: st_info_str = "STT_FUNC";
-       case STT_SECTION: st_info_str = "STT_SECTION";
-       case STT_FILE: st_info_str = "STT_FILE";
-       case STT_OBJECT: st_info_str = "STT_OBJECT";
-       case STT_TLS: st_info_str = "STT_TLS";
-       default: st_info_str = "";
+       case STT_FUNC:
+         st_info_str = "STT_FUNC";
+         break;
+
+       case STT_SECTION:
+         st_info_str = "STT_SECTION";
+         break;
+
+       case STT_FILE:
+         st_info_str = "STT_FILE";
+         break;
+
+       case STT_OBJECT:
+         st_info_str = "STT_OBJECT";
+         break;
+
+       case STT_TLS:
+         st_info_str = "STT_TLS";
+         break;
+
+       default:
+         st_info_str = "";
        }
        }
+
       switch (ELF_ST_BIND (isym->st_info))
        {
       switch (ELF_ST_BIND (isym->st_info))
        {
-       case STB_LOCAL: st_info_stb_str = "STB_LOCAL";
-       case STB_GLOBAL: st_info_stb_str = "STB_GLOBAL";
-       default: st_info_stb_str = "";
+       case STB_LOCAL:
+         st_info_stb_str = "STB_LOCAL";
+         break;
+
+       case STB_GLOBAL:
+         st_info_stb_str = "STB_GLOBAL";
+         break;
+
+       default:
+         st_info_stb_str = "";
        }
        }
+
       switch (ELF_ST_VISIBILITY (isym->st_other))
        {
       switch (ELF_ST_VISIBILITY (isym->st_other))
        {
-       case STV_DEFAULT: st_other_str = "STV_DEFAULT";
-       case STV_INTERNAL: st_other_str = "STV_INTERNAL";
-       case STV_PROTECTED: st_other_str = "STV_PROTECTED";
-       default: st_other_str = "";
+       case STV_DEFAULT:
+         st_other_str = "STV_DEFAULT";
+         break;
+
+       case STV_INTERNAL:
+         st_other_str = "STV_INTERNAL";
+         break;
+
+       case STV_PROTECTED:
+         st_other_str = "STV_PROTECTED";
+         break;
+
+       default:
+         st_other_str = "";
        }
        }
+
       switch (isym->st_shndx)
        {
       switch (isym->st_shndx)
        {
-       case SHN_ABS: st_shndx_str = "SHN_ABS";
-       case SHN_COMMON: st_shndx_str = "SHN_COMMON";
-       case SHN_UNDEF: st_shndx_str = "SHN_UNDEF";
-       default: st_shndx_str = "";
+       case SHN_ABS:
+         st_shndx_str = "SHN_ABS";
+         break;
+
+       case SHN_COMMON:
+         st_shndx_str = "SHN_COMMON";
+         break;
+
+       case SHN_UNDEF:
+         st_shndx_str = "SHN_UNDEF";
+         break;
+
+       default:
+         st_shndx_str = "";
        }
        }
-      
+
       printf ("isym = %p st_value = %lx st_size = %lx st_name = (%lu) %s "
              "st_info = (%d) %s %s st_other = (%d) %s st_shndx = (%d) %s\n",
       printf ("isym = %p st_value = %lx st_size = %lx st_name = (%lu) %s "
              "st_info = (%d) %s %s st_other = (%d) %s st_shndx = (%d) %s\n",
-             isym, 
+             isym,
              (unsigned long) isym->st_value,
              (unsigned long) isym->st_size,
              isym->st_name,
              (unsigned long) isym->st_value,
              (unsigned long) isym->st_size,
              isym->st_name,
@@ -1039,14 +1102,10 @@ struct relax_plt_data
 };
 
 static bfd_boolean
 };
 
 static bfd_boolean
-m32c_relax_plt_check (struct elf_link_hash_entry *h,
-                      PTR xdata)
+m32c_relax_plt_check (struct elf_link_hash_entry *h, void * xdata)
 {
   struct relax_plt_data *data = (struct relax_plt_data *) xdata;
 
 {
   struct relax_plt_data *data = (struct relax_plt_data *) xdata;
 
-  if (h->root.type == bfd_link_hash_warning)
-    h = (struct elf_link_hash_entry *) h->root.u.i.link;
-
   if (h->plt.offset != (bfd_vma) -1)
     {
       bfd_vma address;
   if (h->plt.offset != (bfd_vma) -1)
     {
       bfd_vma address;
@@ -1074,14 +1133,10 @@ m32c_relax_plt_check (struct elf_link_hash_entry *h,
    previously had a plt entry, give it a new entry offset.  */
 
 static bfd_boolean
    previously had a plt entry, give it a new entry offset.  */
 
 static bfd_boolean
-m32c_relax_plt_realloc (struct elf_link_hash_entry *h,
-                        PTR xdata)
+m32c_relax_plt_realloc (struct elf_link_hash_entry *h, void * xdata)
 {
   bfd_vma *entry = (bfd_vma *) xdata;
 
 {
   bfd_vma *entry = (bfd_vma *) xdata;
 
-  if (h->root.type == bfd_link_hash_warning)
-    h = (struct elf_link_hash_entry *) h->root.u.i.link;
-
   if (h->plt.offset != (bfd_vma) -1)
     {
       h->plt.offset = *entry;
   if (h->plt.offset != (bfd_vma) -1)
     {
       h->plt.offset = *entry;
@@ -1092,8 +1147,7 @@ m32c_relax_plt_realloc (struct elf_link_hash_entry *h,
 }
 
 static bfd_boolean
 }
 
 static bfd_boolean
-m32c_elf_relax_plt_section (bfd *dynobj,
-                            asection *splt,
+m32c_elf_relax_plt_section (asection *splt,
                             struct bfd_link_info *info,
                             bfd_boolean *again)
 {
                             struct bfd_link_info *info,
                             bfd_boolean *again)
 {
@@ -1103,12 +1157,7 @@ m32c_elf_relax_plt_section (bfd *dynobj,
   /* Assume nothing changes.  */
   *again = FALSE;
 
   /* Assume nothing changes.  */
   *again = FALSE;
 
-  if (info->relocatable)
-    return TRUE;
-
-  /* We only relax the .plt section at the moment.  */
-  if (dynobj != elf_hash_table (info)->dynobj
-      || strcmp (splt->name, ".plt") != 0)
+  if (bfd_link_relocatable (info))
     return TRUE;
 
   /* Quick check for an empty plt.  */
     return TRUE;
 
   /* Quick check for an empty plt.  */
@@ -1124,7 +1173,7 @@ m32c_elf_relax_plt_section (bfd *dynobj,
 
   /* Likewise for local symbols, though that's somewhat less convenient
      as we have to walk the list of input bfds and swap in symbol data.  */
 
   /* Likewise for local symbols, though that's somewhat less convenient
      as we have to walk the list of input bfds and swap in symbol data.  */
-  for (ibfd = info->input_bfds; ibfd ; ibfd = ibfd->link_next)
+  for (ibfd = info->input_bfds; ibfd ; ibfd = ibfd->link.next)
     {
       bfd_vma *local_plt_offsets = elf_local_got_offsets (ibfd);
       Elf_Internal_Shdr *symtab_hdr;
     {
       bfd_vma *local_plt_offsets = elf_local_got_offsets (ibfd);
       Elf_Internal_Shdr *symtab_hdr;
@@ -1198,7 +1247,7 @@ m32c_elf_relax_plt_section (bfd *dynobj,
       elf_link_hash_traverse (elf_hash_table (info),
                              m32c_relax_plt_realloc, &entry);
 
       elf_link_hash_traverse (elf_hash_table (info),
                              m32c_relax_plt_realloc, &entry);
 
-      for (ibfd = info->input_bfds; ibfd ; ibfd = ibfd->link_next)
+      for (ibfd = info->input_bfds; ibfd ; ibfd = ibfd->link.next)
        {
          bfd_vma *local_plt_offsets = elf_local_got_offsets (ibfd);
          unsigned int nlocals = elf_tdata (ibfd)->symtab_hdr.sh_info;
        {
          bfd_vma *local_plt_offsets = elf_local_got_offsets (ibfd);
          unsigned int nlocals = elf_tdata (ibfd)->symtab_hdr.sh_info;
@@ -1236,7 +1285,7 @@ static bfd_vma
 m32c_offset_for_reloc (bfd *abfd,
                       Elf_Internal_Rela *rel,
                       Elf_Internal_Shdr *symtab_hdr,
 m32c_offset_for_reloc (bfd *abfd,
                       Elf_Internal_Rela *rel,
                       Elf_Internal_Shdr *symtab_hdr,
-                      Elf_External_Sym_Shndx *shndx_buf,
+                      Elf_External_Sym_Shndx *shndx_buf ATTRIBUTE_UNUSED,
                       Elf_Internal_Sym *intsyms)
 {
   bfd_vma symval;
                       Elf_Internal_Sym *intsyms)
 {
   bfd_vma symval;
@@ -1246,14 +1295,10 @@ m32c_offset_for_reloc (bfd *abfd,
     {
       /* A local symbol.  */
       Elf_Internal_Sym *isym;
     {
       /* A local symbol.  */
       Elf_Internal_Sym *isym;
-      Elf_External_Sym_Shndx *shndx;
       asection *ssec;
 
       asection *ssec;
 
-
       isym = intsyms + ELF32_R_SYM (rel->r_info);
       ssec = bfd_section_from_elf_index (abfd, isym->st_shndx);
       isym = intsyms + ELF32_R_SYM (rel->r_info);
       ssec = bfd_section_from_elf_index (abfd, isym->st_shndx);
-      shndx = shndx_buf + (shndx_buf ? ELF32_R_SYM (rel->r_info) : 0);
-
       symval = isym->st_value;
       if (ssec)
        symval += ssec->output_section->vma
       symval = isym->st_value;
       if (ssec)
        symval += ssec->output_section->vma
@@ -1402,8 +1447,9 @@ m32c_elf_relax_section
   int machine;
 
   if (abfd == elf_hash_table (link_info)->dynobj
   int machine;
 
   if (abfd == elf_hash_table (link_info)->dynobj
+      && (sec->flags & SEC_LINKER_CREATED) != 0
       && strcmp (sec->name, ".plt") == 0)
       && strcmp (sec->name, ".plt") == 0)
-    return m32c_elf_relax_plt_section (abfd, sec, link_info, again);
+    return m32c_elf_relax_plt_section (sec, link_info, again);
 
   /* Assume nothing changes.  */
   *again = FALSE;
 
   /* Assume nothing changes.  */
   *again = FALSE;
@@ -1413,14 +1459,17 @@ m32c_elf_relax_section
   /* We don't have to do anything for a relocatable link, if
      this section does not have relocs, or if this is not a
      code section.  */
   /* We don't have to do anything for a relocatable link, if
      this section does not have relocs, or if this is not a
      code section.  */
-  if (link_info->relocatable
+  if (bfd_link_relocatable (link_info)
       || (sec->flags & SEC_RELOC) == 0
       || sec->reloc_count == 0
       || (sec->flags & SEC_CODE) == 0)
     return TRUE;
 
       || (sec->flags & SEC_RELOC) == 0
       || sec->reloc_count == 0
       || (sec->flags & SEC_CODE) == 0)
     return TRUE;
 
-  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
-  shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
+  symtab_hdr = & elf_symtab_hdr (abfd);
+  if (elf_symtab_shndx_list (abfd))
+    shndx_hdr = & elf_symtab_shndx_list (abfd)->hdr;
+  else
+    shndx_hdr = NULL;
 
   /* Get the section contents.  */
   if (elf_section_data (sec)->this_hdr.contents != NULL)
 
   /* Get the section contents.  */
   if (elf_section_data (sec)->this_hdr.contents != NULL)
@@ -1441,7 +1490,7 @@ m32c_elf_relax_section
       symtab_hdr->contents = (bfd_byte *) intsyms;
     }
 
       symtab_hdr->contents = (bfd_byte *) intsyms;
     }
 
-  if (shndx_hdr->sh_size != 0)
+  if (shndx_hdr && shndx_hdr->sh_size != 0)
     {
       bfd_size_type amt;
 
     {
       bfd_size_type amt;
 
@@ -1451,14 +1500,14 @@ m32c_elf_relax_section
       if (shndx_buf == NULL)
        goto error_return;
       if (bfd_seek (abfd, shndx_hdr->sh_offset, SEEK_SET) != 0
       if (shndx_buf == NULL)
        goto error_return;
       if (bfd_seek (abfd, shndx_hdr->sh_offset, SEEK_SET) != 0
-         || bfd_bread ((PTR) shndx_buf, amt, abfd) != amt)
+         || bfd_bread (shndx_buf, amt, abfd) != amt)
        goto error_return;
       shndx_hdr->contents = (bfd_byte *) shndx_buf;
     }
 
   /* Get a copy of the native relocations.  */
   internal_relocs = (_bfd_elf_link_read_relocs
        goto error_return;
       shndx_hdr->contents = (bfd_byte *) shndx_buf;
     }
 
   /* Get a copy of the native relocations.  */
   internal_relocs = (_bfd_elf_link_read_relocs
-                    (abfd, sec, (PTR) NULL, (Elf_Internal_Rela *) NULL,
+                    (abfd, sec, NULL, (Elf_Internal_Rela *) NULL,
                      link_info->keep_memory));
   if (internal_relocs == NULL)
     goto error_return;
                      link_info->keep_memory));
   if (internal_relocs == NULL)
     goto error_return;
@@ -1650,7 +1699,7 @@ m32c_elf_relax_section
 
              enctbl = m16c_addr_encodings;
              posn = 2;
 
              enctbl = m16c_addr_encodings;
              posn = 2;
-             
+
              /* Check the opcode for jumps.  We know it's safe to
                 do this because all 2ADDR insns are at least two
                 bytes long.  */
              /* Check the opcode for jumps.  We know it's safe to
                 do this because all 2ADDR insns are at least two
                 bytes long.  */
@@ -1836,7 +1885,7 @@ m32c_elf_relax_section
       /* Note that we've changed the relocs, section contents, etc.  */
       elf_section_data (sec)->relocs = internal_relocs;
       free_relocs = NULL;
       /* Note that we've changed the relocs, section contents, etc.  */
       elf_section_data (sec)->relocs = internal_relocs;
       free_relocs = NULL;
-      
+
       elf_section_data (sec)->this_hdr.contents = contents;
       free_contents = NULL;
 
       elf_section_data (sec)->this_hdr.contents = contents;
       free_contents = NULL;
 
@@ -1918,7 +1967,6 @@ m32c_elf_relax_delete_bytes
   bfd_byte *contents;
   Elf_Internal_Rela *irel;
   Elf_Internal_Rela *irelend;
   bfd_byte *contents;
   Elf_Internal_Rela *irel;
   Elf_Internal_Rela *irelend;
-  Elf_Internal_Rela *irelalign;
   bfd_vma toaddr;
   Elf_Internal_Sym *isym;
   Elf_Internal_Sym *isymend;
   bfd_vma toaddr;
   Elf_Internal_Sym *isym;
   Elf_Internal_Sym *isymend;
@@ -1931,9 +1979,6 @@ m32c_elf_relax_delete_bytes
 
   contents   = elf_section_data (sec)->this_hdr.contents;
 
 
   contents   = elf_section_data (sec)->this_hdr.contents;
 
-  /* The deletion must stop at the next ALIGN reloc for an aligment
-     power larger than the number of bytes we are deleting.  */
-  irelalign = NULL;
   toaddr = sec->size;
 
   irel = elf_section_data (sec)->relocs;
   toaddr = sec->size;
 
   irel = elf_section_data (sec)->relocs;
@@ -1993,19 +2038,38 @@ m32c_elf_relax_delete_bytes
   isymend = isym + symtab_hdr->sh_info;
 
   sec_shndx  = _bfd_elf_section_from_bfd_section (abfd, sec);
   isymend = isym + symtab_hdr->sh_info;
 
   sec_shndx  = _bfd_elf_section_from_bfd_section (abfd, sec);
-  shndx_hdr  = & elf_tdata (abfd)->symtab_shndx_hdr;
-  shndx_buf  = (Elf_External_Sym_Shndx *) shndx_hdr->contents;
+  if (elf_symtab_shndx_list (abfd))
+    {
+      shndx_hdr = & elf_symtab_shndx_list (abfd)->hdr;
+      shndx_buf  = (Elf_External_Sym_Shndx *) shndx_hdr->contents;
+    }
+  else
+    {
+      shndx_hdr = NULL;
+      shndx_buf = NULL;
+    }
   shndx = shndx_buf;
 
   for (; isym < isymend; isym++, shndx = (shndx ? shndx + 1 : NULL))
     {
   shndx = shndx_buf;
 
   for (; isym < isymend; isym++, shndx = (shndx ? shndx + 1 : NULL))
     {
-
+      /* If the symbol is in the range of memory we just moved, we
+        have to adjust its value.  */
       if ((int) isym->st_shndx == sec_shndx
          && isym->st_value > addr
          && isym->st_value < toaddr)
        {
          isym->st_value -= count;
        }
       if ((int) isym->st_shndx == sec_shndx
          && isym->st_value > addr
          && isym->st_value < toaddr)
        {
          isym->st_value -= count;
        }
+      /* If the symbol *spans* the bytes we just deleted (i.e. it's
+        *end* is in the moved bytes but it's *start* isn't), then we
+        must adjust its size.  */
+      if ((int) isym->st_shndx == sec_shndx
+           && isym->st_value < addr
+         && isym->st_value + isym->st_size > addr
+         && isym->st_value + isym->st_size < toaddr)
+       {
+         isym->st_size -= count;
+       }
     }
 
   /* Now adjust the global symbols defined in this section.  */
     }
 
   /* Now adjust the global symbols defined in this section.  */
@@ -2020,29 +2084,49 @@ m32c_elf_relax_delete_bytes
       struct elf_link_hash_entry * sym_hash = * sym_hashes;
 
       if (sym_hash &&
       struct elf_link_hash_entry * sym_hash = * sym_hashes;
 
       if (sym_hash &&
-         (   sym_hash->root.type == bfd_link_hash_defined
+         (sym_hash->root.type == bfd_link_hash_defined
           || sym_hash->root.type == bfd_link_hash_defweak)
           || sym_hash->root.type == bfd_link_hash_defweak)
-         && sym_hash->root.u.def.section == sec
-         && sym_hash->root.u.def.value > addr
-         && sym_hash->root.u.def.value < toaddr)
+         && sym_hash->root.u.def.section == sec)
        {
        {
-         sym_hash->root.u.def.value -= count;
+         if (sym_hash->root.u.def.value > addr
+             && sym_hash->root.u.def.value < toaddr)
+           {
+             sym_hash->root.u.def.value -= count;
+           }
+         if (sym_hash->root.u.def.value < addr
+             && sym_hash->root.u.def.value + sym_hash->size > addr
+             && sym_hash->root.u.def.value + sym_hash->size < toaddr)
+           {
+             sym_hash->size -= count;
+           }
        }
     }
 
   return TRUE;
 }
        }
     }
 
   return TRUE;
 }
+\f
+/* This is for versions of gcc prior to 4.3.  */
+static unsigned int
+_bfd_m32c_elf_eh_frame_address_size (bfd *abfd,
+                                    const asection *sec ATTRIBUTE_UNUSED)
+{
+  if ((elf_elfheader (abfd)->e_flags & EF_M32C_CPU_MASK) == EF_M32C_CPU_M16C)
+    return 2;
+  return 4;
+}
+
 \f
 
 #define ELF_ARCH               bfd_arch_m32c
 #define ELF_MACHINE_CODE       EM_M32C
 \f
 
 #define ELF_ARCH               bfd_arch_m32c
 #define ELF_MACHINE_CODE       EM_M32C
-#define ELF_MAXPAGESIZE                0x1000
+#define ELF_MACHINE_ALT1       EM_M32C_OLD
+#define ELF_MAXPAGESIZE                0x100
 
 #if 0
 
 #if 0
-#define TARGET_BIG_SYM         bfd_elf32_m32c_vec
+#define TARGET_BIG_SYM         m32c_elf32_vec
 #define TARGET_BIG_NAME                "elf32-m32c"
 #else
 #define TARGET_BIG_NAME                "elf32-m32c"
 #else
-#define TARGET_LITTLE_SYM              bfd_elf32_m32c_vec
+#define TARGET_LITTLE_SYM              m32c_elf32_vec
 #define TARGET_LITTLE_NAME             "elf32-m32c"
 #endif
 
 #define TARGET_LITTLE_NAME             "elf32-m32c"
 #endif
 
@@ -2050,8 +2134,6 @@ m32c_elf_relax_delete_bytes
 #define elf_info_to_howto                      m32c_info_to_howto_rela
 #define elf_backend_object_p                   m32c_elf_object_p
 #define elf_backend_relocate_section           m32c_elf_relocate_section
 #define elf_info_to_howto                      m32c_info_to_howto_rela
 #define elf_backend_object_p                   m32c_elf_object_p
 #define elf_backend_relocate_section           m32c_elf_relocate_section
-#define elf_backend_gc_mark_hook               m32c_elf_gc_mark_hook
-#define elf_backend_gc_sweep_hook              m32c_elf_gc_sweep_hook
 #define elf_backend_check_relocs                m32c_elf_check_relocs
 #define elf_backend_object_p                   m32c_elf_object_p
 #define elf_symbol_leading_char                 ('_')
 #define elf_backend_check_relocs                m32c_elf_check_relocs
 #define elf_backend_object_p                   m32c_elf_object_p
 #define elf_symbol_leading_char                 ('_')
@@ -2061,8 +2143,10 @@ m32c_elf_relax_delete_bytes
   m32c_elf_finish_dynamic_sections
 
 #define elf_backend_can_gc_sections            1
   m32c_elf_finish_dynamic_sections
 
 #define elf_backend_can_gc_sections            1
+#define elf_backend_eh_frame_address_size _bfd_m32c_elf_eh_frame_address_size
 
 #define bfd_elf32_bfd_reloc_type_lookup                m32c_reloc_type_lookup
 
 #define bfd_elf32_bfd_reloc_type_lookup                m32c_reloc_type_lookup
+#define bfd_elf32_bfd_reloc_name_lookup        m32c_reloc_name_lookup
 #define bfd_elf32_bfd_relax_section            m32c_elf_relax_section
 #define bfd_elf32_bfd_set_private_flags                m32c_elf_set_private_flags
 #define bfd_elf32_bfd_merge_private_bfd_data   m32c_elf_merge_private_bfd_data
 #define bfd_elf32_bfd_relax_section            m32c_elf_relax_section
 #define bfd_elf32_bfd_set_private_flags                m32c_elf_set_private_flags
 #define bfd_elf32_bfd_merge_private_bfd_data   m32c_elf_merge_private_bfd_data
This page took 0.03761 seconds and 4 git commands to generate.