Fix regression caused by recently added syscall restart code
[external/binutils.git] / bfd / elf32-cr16c.c
index 1f0bf15..9a2fda0 100644 (file)
@@ -1,11 +1,11 @@
 /* BFD back-end for National Semiconductor's CR16C ELF
 /* BFD back-end for National Semiconductor's CR16C ELF
-   Copyright 2004, 2005 Free Software Foundation, Inc.
+   Copyright (C) 2004-2019 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,
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
 
 
-#include "bfd.h"
 #include "sysdep.h"
 #include "sysdep.h"
+#include "bfd.h"
 #include "libbfd.h"
 #include "bfdlink.h"
 #include "elf/cr16c.h"
 #include "libbfd.h"
 #include "bfdlink.h"
 #include "elf/cr16c.h"
 
 #define USE_REL        1       /* CR16C uses REL relocations instead of RELA.  */
 
 
 #define USE_REL        1       /* CR16C uses REL relocations instead of RELA.  */
 
-/* The following definition is based on EMPTY_HOWTO macro, 
+/* The following definition is based on EMPTY_HOWTO macro,
    but also initiates the "name" field in HOWTO struct.  */
 #define ONLY_NAME_HOWTO(C) \
   HOWTO ((C), 0, 0, 0, FALSE, 0, complain_overflow_dont, NULL, \
          STRINGX(C), FALSE, 0, 0, FALSE)
 
 /* reloc_map_index array maps CRASM relocation type into a BFD
    but also initiates the "name" field in HOWTO struct.  */
 #define ONLY_NAME_HOWTO(C) \
   HOWTO ((C), 0, 0, 0, FALSE, 0, complain_overflow_dont, NULL, \
          STRINGX(C), FALSE, 0, 0, FALSE)
 
 /* reloc_map_index array maps CRASM relocation type into a BFD
-   relocation enum. The array's indices are synchronized with 
+   relocation enum. The array's indices are synchronized with
    RINDEX_16C_* indices, created in include/elf/cr16c.h.
    The array is used in:
    1. elf32-cr16c.c : elf_cr16c_reloc_type_lookup().
    RINDEX_16C_* indices, created in include/elf/cr16c.h.
    The array is used in:
    1. elf32-cr16c.c : elf_cr16c_reloc_type_lookup().
@@ -150,23 +151,45 @@ elf_cr16c_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
   return 0;
 }
 
   return 0;
 }
 
-static void
+static reloc_howto_type *
+elf_cr16c_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+                            const char *r_name)
+{
+  unsigned int i;
+
+  for (i = 0; i < sizeof (elf_howto_table) / sizeof (elf_howto_table[0]); i++)
+    if (elf_howto_table[i].name != NULL
+       && strcasecmp (elf_howto_table[i].name, r_name) == 0)
+      return &elf_howto_table[i];
+
+  return NULL;
+}
+
+static bfd_boolean
 elf_cr16c_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
                         arelent *cache_ptr ATTRIBUTE_UNUSED,
                         Elf_Internal_Rela *dst ATTRIBUTE_UNUSED)
 {
 elf_cr16c_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
                         arelent *cache_ptr ATTRIBUTE_UNUSED,
                         Elf_Internal_Rela *dst ATTRIBUTE_UNUSED)
 {
-  abort ();
+  return FALSE;
 }
 
 }
 
-static void
+static bfd_boolean
 elf_cr16c_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED,
                             arelent *cache_ptr,
                             Elf_Internal_Rela *dst)
 {
   unsigned int r_type = ELF32_R_TYPE (dst->r_info);
 
 elf_cr16c_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED,
                             arelent *cache_ptr,
                             Elf_Internal_Rela *dst)
 {
   unsigned int r_type = ELF32_R_TYPE (dst->r_info);
 
-  BFD_ASSERT (r_type < (unsigned int) RINDEX_16C_MAX);
+  if (r_type >= RINDEX_16C_MAX)
+    {
+      /* xgettext:c-format */
+      _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
+                         abfd, r_type);
+      bfd_set_error (bfd_error_bad_value);
+      return FALSE;
+    }
   cache_ptr->howto = &elf_howto_table[r_type];
   cache_ptr->howto = &elf_howto_table[r_type];
+  return TRUE;
 }
 
 /* Perform a relocation as part of a final link.  */
 }
 
 /* Perform a relocation as part of a final link.  */
@@ -189,7 +212,6 @@ cr16c_elf_final_link_relocate (reloc_howto_type *howto,
   unsigned long format, addr_type, code_factor;
   unsigned short size;
   unsigned short r_type;
   unsigned long format, addr_type, code_factor;
   unsigned short size;
   unsigned short r_type;
-  asymbol *symbol = NULL;
 
   unsigned long disp20_opcod;
   char neg = 0;
 
   unsigned long disp20_opcod;
   char neg = 0;
@@ -209,18 +231,15 @@ cr16c_elf_final_link_relocate (reloc_howto_type *howto,
   addr_type = r_type & R_ADDRTYPE;
   code_factor = ((addr_type == R_CODE_ADDR) ? 1 : 0);
 
   addr_type = r_type & R_ADDRTYPE;
   code_factor = ((addr_type == R_CODE_ADDR) ? 1 : 0);
 
-  if (sym_sec)
-    symbol = sym_sec->symbol;
-
   switch (format)
     {
     case R_NUMBER:
       switch (size)
        {
   switch (format)
     {
     case R_NUMBER:
       switch (size)
        {
-       case R_S_16C_08:        /* One byte.  */
+       case R_S_16C_08:        /* One byte.  */
          value = bfd_get_8 (abfd, (char *) data + octets);
          break;
          value = bfd_get_8 (abfd, (char *) data + octets);
          break;
-       case R_S_16C_16:        /* Two bytes. */
+       case R_S_16C_16:        /* Two bytes. */
          sword = bfd_get_16 (abfd, (bfd_byte *) data + octets);
          value = sword;
          break;
          sword = bfd_get_16 (abfd, (bfd_byte *) data + octets);
          value = sword;
          break;
@@ -421,7 +440,7 @@ cr16c_elf_final_link_relocate (reloc_howto_type *howto,
     case R_NUMBER:
       switch (size)
        {
     case R_NUMBER:
       switch (size)
        {
-       case R_S_16C_08:        /* One byte.  */
+       case R_S_16C_08:        /* One byte.  */
          if (value > (int) MAX_UBYTE || value < MIN_BYTE)
            return bfd_reloc_overflow;
          value &= 0xFF;
          if (value > (int) MAX_UBYTE || value < MIN_BYTE)
            return bfd_reloc_overflow;
          value &= 0xFF;
@@ -566,7 +585,7 @@ cr16c_elf_final_link_relocate (reloc_howto_type *howto,
          if (neg2pos)
            {
              /* Change load/stor negative displ opcode
          if (neg2pos)
            {
              /* Change load/stor negative displ opcode
-                to load/stor positive displ opcode.  */
+                to load/stor positive displ opcode.  */
              value = bfd_get_8 (abfd, (char *) data + octets - 3);
              value &= 0xF7;
              value |= 0x2;
              value = bfd_get_8 (abfd, (char *) data + octets - 3);
              value &= 0xF7;
              value |= 0x2;
@@ -692,26 +711,6 @@ elf32_cr16c_relocate_section (bfd *output_bfd,
       r_type = ELF32_R_TYPE (rel->r_info);
       howto = elf_howto_table + r_type;
 
       r_type = ELF32_R_TYPE (rel->r_info);
       howto = elf_howto_table + r_type;
 
-      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;
-       }
-
-      /* This is a final link.  */
       h = NULL;
       sym = NULL;
       sec = NULL;
       h = NULL;
       sym = NULL;
       sec = NULL;
@@ -723,12 +722,27 @@ elf32_cr16c_relocate_section (bfd *output_bfd,
        }
       else
        {
        }
       else
        {
-         bfd_boolean unresolved_reloc, warned;
+         bfd_boolean unresolved_reloc, warned, ignored;
 
          RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
                                   r_symndx, symtab_hdr, sym_hashes,
                                   h, sec, relocation,
 
          RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
                                   r_symndx, symtab_hdr, sym_hashes,
                                   h, sec, relocation,
-                                  unresolved_reloc, warned);
+                                  unresolved_reloc, warned, ignored);
+       }
+
+      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;
        }
 
       r = cr16c_elf_final_link_relocate (howto, input_bfd, output_bfd,
        }
 
       r = cr16c_elf_final_link_relocate (howto, input_bfd, output_bfd,
@@ -755,18 +769,14 @@ elf32_cr16c_relocate_section (bfd *output_bfd,
          switch (r)
            {
            case bfd_reloc_overflow:
          switch (r)
            {
            case bfd_reloc_overflow:
-             if (!((*info->callbacks->reloc_overflow)
-                   (info, (h ? &h->root : NULL), name, howto->name,
-                    (bfd_vma) 0, input_bfd, input_section,
-                    rel->r_offset)))
-               return FALSE;
+             (*info->callbacks->reloc_overflow)
+               (info, (h ? &h->root : NULL), name, howto->name,
+                (bfd_vma) 0, input_bfd, input_section, rel->r_offset);
              break;
 
            case bfd_reloc_undefined:
              break;
 
            case bfd_reloc_undefined:
-             if (!((*info->callbacks->undefined_symbol)
-                   (info, name, input_bfd, input_section,
-                    rel->r_offset, TRUE)))
-               return FALSE;
+             (*info->callbacks->undefined_symbol)
+               (info, name, input_bfd, input_section, rel->r_offset, TRUE);
              break;
 
            case bfd_reloc_outofrange:
              break;
 
            case bfd_reloc_outofrange:
@@ -786,10 +796,8 @@ elf32_cr16c_relocate_section (bfd *output_bfd,
              /* fall through */
 
            common_error:
              /* fall through */
 
            common_error:
-             if (!((*info->callbacks->warning)
-                   (info, msg, name, input_bfd, input_section,
-                    rel->r_offset)))
-               return FALSE;
+             (*info->callbacks->warning) (info, msg, name, input_bfd,
+                                          input_section, rel->r_offset);
              break;
            }
        }
              break;
            }
        }
@@ -798,53 +806,6 @@ elf32_cr16c_relocate_section (bfd *output_bfd,
   return TRUE;
 }
 
   return TRUE;
 }
 
-static asection *
-elf32_cr16c_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
-    {
-      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
-elf32_cr16c_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)
-{
-  /* We don't support garbage collection of GOT and PLT relocs yet.  */
-  return TRUE;
-}
-
 /* CR16C ELF uses three common sections:
    One is for default common symbols (placed in usual common section).
    Second is for near common symbols (placed in "ncommon" section).
 /* CR16C ELF uses three common sections:
    One is for default common symbols (placed in usual common section).
    Second is for near common symbols (placed in "ncommon" section).
@@ -957,7 +918,7 @@ elf32_cr16c_add_symbol_hook (bfd *abfd,
   return TRUE;
 }
 
   return TRUE;
 }
 
-static bfd_boolean
+static int
 elf32_cr16c_link_output_symbol_hook (struct bfd_link_info *info ATTRIBUTE_UNUSED,
                                     const char *name ATTRIBUTE_UNUSED,
                                     Elf_Internal_Sym *sym,
 elf32_cr16c_link_output_symbol_hook (struct bfd_link_info *info ATTRIBUTE_UNUSED,
                                     const char *name ATTRIBUTE_UNUSED,
                                     Elf_Internal_Sym *sym,
@@ -976,11 +937,11 @@ elf32_cr16c_link_output_symbol_hook (struct bfd_link_info *info ATTRIBUTE_UNUSED
        sym->st_shndx = SHN_CR16C_NCOMMON;
     }
 
        sym->st_shndx = SHN_CR16C_NCOMMON;
     }
 
-  return TRUE;
+  return 1;
 }
 
 /* Definitions for setting CR16C target vector.  */
 }
 
 /* Definitions for setting CR16C target vector.  */
-#define TARGET_LITTLE_SYM              bfd_elf32_cr16c_vec
+#define TARGET_LITTLE_SYM              cr16c_elf32_vec
 #define TARGET_LITTLE_NAME             "elf32-cr16c"
 #define ELF_ARCH                       bfd_arch_cr16c
 #define ELF_MACHINE_CODE               EM_CR
 #define TARGET_LITTLE_NAME             "elf32-cr16c"
 #define ELF_ARCH                       bfd_arch_cr16c
 #define ELF_MACHINE_CODE               EM_CR
@@ -988,15 +949,14 @@ elf32_cr16c_link_output_symbol_hook (struct bfd_link_info *info ATTRIBUTE_UNUSED
 #define elf_symbol_leading_char                '_'
 
 #define bfd_elf32_bfd_reloc_type_lookup                elf_cr16c_reloc_type_lookup
 #define elf_symbol_leading_char                '_'
 
 #define bfd_elf32_bfd_reloc_type_lookup                elf_cr16c_reloc_type_lookup
+#define bfd_elf32_bfd_reloc_name_lookup        elf_cr16c_reloc_name_lookup
 #define elf_info_to_howto                      elf_cr16c_info_to_howto
 #define elf_info_to_howto_rel                  elf_cr16c_info_to_howto_rel
 #define elf_backend_relocate_section           elf32_cr16c_relocate_section
 #define elf_info_to_howto                      elf_cr16c_info_to_howto
 #define elf_info_to_howto_rel                  elf_cr16c_info_to_howto_rel
 #define elf_backend_relocate_section           elf32_cr16c_relocate_section
-#define elf_backend_gc_mark_hook               elf32_cr16c_gc_mark_hook
-#define elf_backend_gc_sweep_hook              elf32_cr16c_gc_sweep_hook
 #define elf_backend_symbol_processing          elf32_cr16c_symbol_processing
 #define elf_backend_symbol_processing          elf32_cr16c_symbol_processing
-#define elf_backend_section_from_bfd_section   elf32_cr16c_section_from_bfd_section
+#define elf_backend_section_from_bfd_section   elf32_cr16c_section_from_bfd_section
 #define elf_backend_add_symbol_hook            elf32_cr16c_add_symbol_hook
 #define elf_backend_add_symbol_hook            elf32_cr16c_add_symbol_hook
-#define elf_backend_link_output_symbol_hook    elf32_cr16c_link_output_symbol_hook
+#define elf_backend_link_output_symbol_hook    elf32_cr16c_link_output_symbol_hook
 
 #define elf_backend_can_gc_sections     1
 
 
 #define elf_backend_can_gc_sections     1