PR26069, strip/objcopy misaligned address accesses
[deliverable/binutils-gdb.git] / bfd / elf32-m32r.c
index 78d5e3966743eb447debe693360defe7ddef196f..c147b713de360e73293a5fb0974ff037ec34b2f6 100644 (file)
@@ -1,5 +1,5 @@
 /* M32R-specific support for 32-bit ELF.
-   Copyright (C) 1996-2018 Free Software Foundation, Inc.
+   Copyright (C) 1996-2020 Free Software Foundation, Inc.
 
    This file is part of BFD, the Binary File Descriptor library.
 
@@ -1272,7 +1272,7 @@ bfd_elf32_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
 
 /* Set the howto pointer for an M32R ELF reloc.  */
 
-static void
+static bfd_boolean
 m32r_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED,
                        arelent *cache_ptr,
                        Elf_Internal_Rela *dst)
@@ -1283,21 +1283,34 @@ m32r_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED,
   if (r_type > (unsigned int) R_M32R_GNU_VTENTRY)
     {
       /* xgettext:c-format */
-      _bfd_error_handler (_("%B: invalid M32R reloc number: %d"), abfd, r_type);
-      r_type = 0;
+      _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
+                         abfd, r_type);
+      bfd_set_error (bfd_error_bad_value);
+      return FALSE;
     }
   cache_ptr->howto = &m32r_elf_howto_table[r_type];
+  return TRUE;
 }
 
-static void
+static bfd_boolean
 m32r_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
                    arelent *cache_ptr,
                    Elf_Internal_Rela *dst)
 {
-  BFD_ASSERT ((ELF32_R_TYPE(dst->r_info) == (unsigned int) R_M32R_NONE)
-             || ((ELF32_R_TYPE(dst->r_info) > (unsigned int) R_M32R_GNU_VTENTRY)
-                 && (ELF32_R_TYPE(dst->r_info) < (unsigned int) R_M32R_max)));
-  cache_ptr->howto = &m32r_elf_howto_table[ELF32_R_TYPE(dst->r_info)];
+  unsigned int r_type = ELF32_R_TYPE (dst->r_info);
+
+  if (r_type == (unsigned int) R_M32R_NONE
+      || ((r_type > (unsigned int) R_M32R_GNU_VTENTRY)
+         && (r_type < (unsigned int) R_M32R_max)))
+    {
+      cache_ptr->howto = &m32r_elf_howto_table[r_type];
+      return TRUE;
+    }
+
+  /* xgettext:c-format */
+  _bfd_error_handler (_("%pB: unsupported relocation type %#x"), abfd, r_type);
+  bfd_set_error (bfd_error_bad_value);
+  return FALSE;
 }
 
 \f
@@ -1309,7 +1322,7 @@ _bfd_m32r_elf_section_from_bfd_section (bfd *abfd ATTRIBUTE_UNUSED,
                                        asection *sec,
                                        int *retval)
 {
-  if (strcmp (bfd_get_section_name (abfd, sec), ".scommon") == 0)
+  if (strcmp (bfd_section_name (sec), ".scommon") == 0)
     {
       *retval = SHN_M32R_SCOMMON;
       return TRUE;
@@ -1394,7 +1407,7 @@ m32r_elf_add_symbol_hook (bfd *abfd,
                                                  flags);
          if (s == NULL)
            return FALSE;
-         if (! bfd_set_section_alignment (abfd, s, 2))
+         if (!bfd_set_section_alignment (s, 2))
            return FALSE;
        }
 
@@ -1485,16 +1498,6 @@ struct elf_m32r_pcrel_relocs_copied
   bfd_size_type count;
 };
 
-/* m32r ELF linker hash entry.  */
-
-struct elf_m32r_link_hash_entry
-{
-  struct elf_link_hash_entry root;
-
-  /* Track dynamic relocs copied for this symbol.  */
-  struct elf_dyn_relocs *dyn_relocs;
-};
-
 /* m32r ELF linker hash table.  */
 
 struct elf_m32r_link_hash_table
@@ -1523,54 +1526,21 @@ struct elf_m32r_link_hash_table
   (elf_hash_table_id ((struct elf_link_hash_table *) ((p)->hash)) \
   == M32R_ELF_DATA ? ((struct elf_m32r_link_hash_table *) ((p)->hash)) : NULL)
 
-/* Create an entry in an m32r ELF linker hash table.  */
-
-static struct bfd_hash_entry *
-m32r_elf_link_hash_newfunc (struct bfd_hash_entry *entry,
-                           struct bfd_hash_table *table,
-                           const char *string)
-{
-  struct elf_m32r_link_hash_entry *ret =
-    (struct elf_m32r_link_hash_entry *) entry;
-
-  /* Allocate the structure if it has not already been allocated by a
-     subclass.  */
-  if (ret == NULL)
-    ret = bfd_hash_allocate (table,
-                            sizeof (struct elf_m32r_link_hash_entry));
-  if (ret == NULL)
-    return NULL;
-
-  /* Call the allocation method of the superclass.  */
-  ret = ((struct elf_m32r_link_hash_entry *)
-        _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret,
-                                    table, string));
-  if (ret != NULL)
-    {
-      struct elf_m32r_link_hash_entry *eh;
-
-      eh = (struct elf_m32r_link_hash_entry *) ret;
-      eh->dyn_relocs = NULL;
-    }
-
-  return (struct bfd_hash_entry *) ret;
-}
-
 /* Create an m32r ELF linker hash table.  */
 
 static struct bfd_link_hash_table *
 m32r_elf_link_hash_table_create (bfd *abfd)
 {
   struct elf_m32r_link_hash_table *ret;
-  bfd_size_type amt = sizeof (struct elf_m32r_link_hash_table);
+  size_t amt = sizeof (struct elf_m32r_link_hash_table);
 
   ret = bfd_zmalloc (amt);
   if (ret == NULL)
     return NULL;
 
   if (!_bfd_elf_link_hash_table_init (&ret->root, abfd,
-                                     m32r_elf_link_hash_newfunc,
-                                     sizeof (struct elf_m32r_link_hash_entry),
+                                     _bfd_elf_link_hash_newfunc,
+                                     sizeof (struct elf_link_hash_entry),
                                      M32R_ELF_DATA))
     {
       free (ret);
@@ -1610,7 +1580,7 @@ m32r_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
   s = bfd_make_section_anyway_with_flags (abfd, ".plt", pltflags);
   htab->root.splt = s;
   if (s == NULL
-      || ! bfd_set_section_alignment (abfd, s, bed->plt_alignment))
+      || !bfd_set_section_alignment (s, bed->plt_alignment))
     return FALSE;
 
   if (bed->want_plt_sym)
@@ -1641,7 +1611,7 @@ m32r_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
                                          flags | SEC_READONLY);
   htab->root.srelplt = s;
   if (s == NULL
-      || ! bfd_set_section_alignment (abfd, s, ptralign))
+      || !bfd_set_section_alignment (s, ptralign))
     return FALSE;
 
   if (htab->root.sgot == NULL
@@ -1680,7 +1650,7 @@ m32r_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
                                                  flags | SEC_READONLY);
          htab->srelbss = s;
          if (s == NULL
-             || ! bfd_set_section_alignment (abfd, s, ptralign))
+             || !bfd_set_section_alignment (s, ptralign))
            return FALSE;
        }
     }
@@ -1695,26 +1665,20 @@ m32r_elf_copy_indirect_symbol (struct bfd_link_info *info,
                               struct elf_link_hash_entry *dir,
                               struct elf_link_hash_entry *ind)
 {
-  struct elf_m32r_link_hash_entry * edir;
-  struct elf_m32r_link_hash_entry * eind;
-
-  edir = (struct elf_m32r_link_hash_entry *) dir;
-  eind = (struct elf_m32r_link_hash_entry *) ind;
-
-  if (eind->dyn_relocs != NULL)
+  if (ind->dyn_relocs != NULL)
     {
-      if (edir->dyn_relocs != NULL)
+      if (dir->dyn_relocs != NULL)
        {
          struct elf_dyn_relocs **pp;
          struct elf_dyn_relocs *p;
 
          /* Add reloc counts against the indirect sym to the direct sym
             list.  Merge any entries against the same section.  */
-         for (pp = &eind->dyn_relocs; (p = *pp) != NULL;)
+         for (pp = &ind->dyn_relocs; (p = *pp) != NULL;)
            {
              struct elf_dyn_relocs *q;
 
-             for (q = edir->dyn_relocs; q != NULL; q = q->next)
+             for (q = dir->dyn_relocs; q != NULL; q = q->next)
                if (q->sec == p->sec)
                  {
                    q->pc_count += p->pc_count;
@@ -1725,11 +1689,11 @@ m32r_elf_copy_indirect_symbol (struct bfd_link_info *info,
              if (q == NULL)
                pp = &p->next;
            }
-         *pp = edir->dyn_relocs;
+         *pp = dir->dyn_relocs;
        }
 
-      edir->dyn_relocs = eind->dyn_relocs;
-      eind->dyn_relocs = NULL;
+      dir->dyn_relocs = ind->dyn_relocs;
+      ind->dyn_relocs = NULL;
     }
 
   _bfd_elf_link_hash_copy_indirect (info, dir, ind);
@@ -1742,9 +1706,8 @@ static asection *
 readonly_dynrelocs (struct elf_link_hash_entry *h)
 {
   struct elf_dyn_relocs *p;
-  struct elf_m32r_link_hash_entry *eh = (struct elf_m32r_link_hash_entry *) h;
 
-  for (p = eh->dyn_relocs; p != NULL; p = p->next)
+  for (p = h->dyn_relocs; p != NULL; p = p->next)
     {
       asection *s = p->sec->output_section;
 
@@ -1892,7 +1855,6 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
 {
   struct bfd_link_info *info;
   struct elf_m32r_link_hash_table *htab;
-  struct elf_m32r_link_hash_entry *eh;
   struct elf_dyn_relocs *p;
 
   if (h->root.type == bfd_link_hash_indirect)
@@ -1903,8 +1865,6 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
   if (htab == NULL)
     return FALSE;
 
-  eh = (struct elf_m32r_link_hash_entry *) h;
-
   if (htab->root.dynamic_sections_created
       && h->plt.refcount > 0)
     {
@@ -1987,7 +1947,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
   else
     h->got.offset = (bfd_vma) -1;
 
-  if (eh->dyn_relocs == NULL)
+  if (h->dyn_relocs == NULL)
     return TRUE;
 
   /* In the shared -Bsymbolic case, discard space allocated for
@@ -2004,7 +1964,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
        {
          struct elf_dyn_relocs **pp;
 
-         for (pp = &eh->dyn_relocs; (p = *pp) != NULL;)
+         for (pp = &h->dyn_relocs; (p = *pp) != NULL;)
            {
              p->count -= p->pc_count;
              p->pc_count = 0;
@@ -2017,11 +1977,11 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
 
       /* Also discard relocs on undefined weak syms with non-default
         visibility.  */
-      if (eh->dyn_relocs != NULL
+      if (h->dyn_relocs != NULL
          && h->root.type == bfd_link_hash_undefweak)
        {
          if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
-           eh->dyn_relocs = NULL;
+           h->dyn_relocs = NULL;
 
          /* Make sure undefined weak symbols are output as a dynamic
             symbol in PIEs.  */
@@ -2061,13 +2021,13 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
            goto keep;
        }
 
-      eh->dyn_relocs = NULL;
+      h->dyn_relocs = NULL;
 
     keep: ;
     }
 
   /* Finally, allocate space.  */
-  for (p = eh->dyn_relocs; p != NULL; p = p->next)
+  for (p = h->dyn_relocs; p != NULL; p = p->next)
     {
       asection *sreloc = elf_section_data (p->sec)->sreloc;
       sreloc->size += p->count * sizeof (Elf32_External_Rela);
@@ -2094,7 +2054,7 @@ maybe_set_textrel (struct elf_link_hash_entry *h, void *info_p)
 
       info->flags |= DF_TEXTREL;
       info->callbacks->minfo
-       (_("%B: dynamic relocation against `%T' in read-only section `%A'\n"),
+       (_("%pB: dynamic relocation against `%pT' in read-only section `%pA'\n"),
         sec->owner, h->root.root.string, sec);
 
       /* Not an error, just cut short the traversal.  */
@@ -2221,7 +2181,7 @@ m32r_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
          /* Strip this section if we don't need it; see the
             comment below.  */
        }
-      else if (CONST_STRNEQ (bfd_get_section_name (dynobj, s), ".rela"))
+      else if (CONST_STRNEQ (bfd_section_name (s), ".rela"))
        {
          if (s->size != 0 && s != htab->root.srelplt)
            relocs = TRUE;
@@ -2401,7 +2361,7 @@ m32r_elf_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
       if (r_type < 0 || r_type >= (int) R_M32R_max)
        {
          /* xgettext:c-format */
-         _bfd_error_handler (_("%B: unknown relocation type %d"),
+         _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
                              input_bfd, (int) r_type);
          bfd_set_error (bfd_error_bad_value);
          ret = FALSE;
@@ -2523,11 +2483,11 @@ m32r_elf_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
                {
                  _bfd_error_handler
                    /* xgettext:c-format */
-                   (_("%B(%A+%#Lx): unresolvable %s relocation "
+                   (_("%pB(%pA+%#" PRIx64 "): unresolvable %s relocation "
                       "against symbol `%s'"),
                     input_bfd,
                     input_section,
-                    rel->r_offset,
+                    (uint64_t) rel->r_offset,
                     howto->name,
                     h->root.root.string);
                }
@@ -2538,12 +2498,12 @@ m32r_elf_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
                   && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
            ;
          else if (!bfd_link_relocatable (info))
-           (*info->callbacks->undefined_symbol)
-             (info, h->root.root.string, input_bfd,
-              input_section, offset,
-              (info->unresolved_syms_in_objects == RM_GENERATE_ERROR
-               || ELF_ST_VISIBILITY (h->other)));
-       }
+            info->callbacks->undefined_symbol
+             (info, h->root.root.string, input_bfd, input_section, offset,
+              (info->unresolved_syms_in_objects == RM_DIAGNOSE
+               && !info->warn_unresolved_syms)
+              || ELF_ST_VISIBILITY (h->other));
+        }
 
       if (sec != NULL && discarded_section (sec))
        RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
@@ -2941,7 +2901,7 @@ m32r_elf_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
                const char *name;
 
                BFD_ASSERT (sec != NULL);
-               name = bfd_get_section_name (sec->owner, sec);
+               name = bfd_section_name (sec);
 
                if (   strcmp (name, ".sdata") == 0
                    || strcmp (name, ".sbss") == 0
@@ -2968,7 +2928,8 @@ m32r_elf_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
                  {
                    _bfd_error_handler
                      /* xgettext:c-format */
-                     (_("%B: The target (%s) of an %s relocation is in the wrong section (%A)"),
+                     (_("%pB: the target (%s) of an %s relocation"
+                        " is in the wrong section (%pA)"),
                       input_bfd,
                       sym_name,
                       m32r_elf_howto_table[(int) r_type].name,
@@ -3008,7 +2969,7 @@ m32r_elf_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
              name = (bfd_elf_string_from_elf_section
                      (input_bfd, symtab_hdr->sh_link, sym->st_name));
              if (name == NULL || *name == '\0')
-               name = bfd_section_name (input_bfd, sec);
+               name = bfd_section_name (sec);
            }
 
          if (errmsg != NULL)
@@ -3389,9 +3350,8 @@ m32r_elf_object_p (bfd *abfd)
 
 /* Store the machine number in the flags field.  */
 
-static void
-m32r_elf_final_write_processing (bfd *abfd,
-                                bfd_boolean linker ATTRIBUTE_UNUSED)
+static bfd_boolean
+m32r_elf_final_write_processing (bfd *abfd)
 {
   unsigned long val;
 
@@ -3405,6 +3365,7 @@ m32r_elf_final_write_processing (bfd *abfd,
 
   elf_elfheader (abfd)->e_flags &=~ EF_M32R_ARCH;
   elf_elfheader (abfd)->e_flags |= val;
+  return _bfd_elf_final_write_processing (abfd);
 }
 
 /* Function to keep M32R specific file flags.  */
@@ -3470,7 +3431,7 @@ m32r_elf_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
          || ((in_flags  & EF_M32R_ARCH) == E_M32R2_ARCH))
        {
          _bfd_error_handler
-           (_("%B: Instruction set mismatch with previous modules"), ibfd);
+           (_("%pB: instruction set mismatch with previous modules"), ibfd);
 
          bfd_set_error (bfd_error_bad_value);
          return FALSE;
@@ -3737,7 +3698,7 @@ m32r_elf_check_relocs (bfd *abfd,
              /* If this is a global symbol, we count the number of
                 relocations we need for this symbol.  */
              if (h != NULL)
-               head = &((struct elf_m32r_link_hash_entry *) h)->dyn_relocs;
+               head = &h->dyn_relocs;
              else
                {
                  /* Track dynamic relocs needed for local syms too.  */
@@ -3761,7 +3722,7 @@ m32r_elf_check_relocs (bfd *abfd,
              p = *head;
              if (p == NULL || p->sec != sec)
                {
-                 bfd_size_type amt = sizeof (*p);
+                 size_t amt = sizeof (*p);
 
                  p = bfd_alloc (dynobj, amt);
                  if (p == NULL)
@@ -3793,15 +3754,11 @@ m32r_elf_check_relocs (bfd *abfd,
        /* This relocation describes which C++ vtable entries are actually
           used.  Record for later use during GC.  */
        case R_M32R_GNU_VTENTRY:
-         BFD_ASSERT (h != NULL);
-         if (h != NULL
-             && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_offset))
+         if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_offset))
            return FALSE;
          break;
        case R_M32R_RELA_GNU_VTENTRY:
-         BFD_ASSERT (h != NULL);
-         if (h != NULL
-             && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
+         if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
            return FALSE;
          break;
        }
@@ -3817,6 +3774,18 @@ static const struct bfd_elf_special_section m32r_elf_special_sections[] =
   { NULL,                    0,  0, 0,            0 }
 };
 
+static bfd_boolean
+m32r_elf_section_flags (const Elf_Internal_Shdr *hdr)
+{
+  const char *name = hdr->bfd_section->name;
+
+  if (strncmp (name, ".sbss", 5) == 0
+      || strncmp (name, ".sdata", 6) == 0)
+    hdr->bfd_section->flags |= SEC_SMALL_DATA;
+
+  return TRUE;
+}
+
 static enum elf_reloc_type_class
 m32r_elf_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
                           const asection *rel_sec ATTRIBUTE_UNUSED,
@@ -3854,8 +3823,7 @@ m32r_elf_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
 #define elf_backend_create_dynamic_sections    m32r_elf_create_dynamic_sections
 #define bfd_elf32_bfd_link_hash_table_create   m32r_elf_link_hash_table_create
 #define elf_backend_size_dynamic_sections      m32r_elf_size_dynamic_sections
-#define elf_backend_omit_section_dynsym \
-  ((bfd_boolean (*) (bfd *, struct bfd_link_info *, asection *)) bfd_true)
+#define elf_backend_omit_section_dynsym                _bfd_elf_omit_section_dynsym_all
 #define elf_backend_finish_dynamic_sections    m32r_elf_finish_dynamic_sections
 #define elf_backend_adjust_dynamic_symbol      m32r_elf_adjust_dynamic_symbol
 #define elf_backend_finish_dynamic_symbol      m32r_elf_finish_dynamic_symbol
@@ -3888,6 +3856,7 @@ m32r_elf_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
 #define bfd_elf32_bfd_set_private_flags                m32r_elf_set_private_flags
 #define bfd_elf32_bfd_print_private_bfd_data   m32r_elf_print_private_bfd_data
 #define elf_backend_special_sections           m32r_elf_special_sections
+#define elf_backend_section_flags              m32r_elf_section_flags
 
 #define elf_backend_linux_prpsinfo32_ugid16    TRUE
 
This page took 0.03004 seconds and 4 git commands to generate.