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
-   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
-   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,
 
    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 "bfd.h"
 #include "libbfd.h"
 #include "bfdlink.h"
 #include "elf/cr16c.h"
 
 #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
-   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().
@@ -150,23 +151,45 @@ elf_cr16c_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
   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)
 {
-  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);
 
-  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];
+  return TRUE;
 }
 
 /* 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;
-  asymbol *symbol = NULL;
 
   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);
 
-  if (sym_sec)
-    symbol = sym_sec->symbol;
-
   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;
-       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;
@@ -421,7 +440,7 @@ cr16c_elf_final_link_relocate (reloc_howto_type *howto,
     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;
@@ -566,7 +585,7 @@ cr16c_elf_final_link_relocate (reloc_howto_type *howto,
          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;
@@ -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;
 
-      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;
@@ -723,12 +722,27 @@ elf32_cr16c_relocate_section (bfd *output_bfd,
        }
       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,
-                                  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,
@@ -755,18 +769,14 @@ elf32_cr16c_relocate_section (bfd *output_bfd,
          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:
-             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:
@@ -786,10 +796,8 @@ elf32_cr16c_relocate_section (bfd *output_bfd,
              /* 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;
            }
        }
@@ -798,53 +806,6 @@ elf32_cr16c_relocate_section (bfd *output_bfd,
   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).
@@ -957,7 +918,7 @@ elf32_cr16c_add_symbol_hook (bfd *abfd,
   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,
@@ -976,11 +937,11 @@ elf32_cr16c_link_output_symbol_hook (struct bfd_link_info *info ATTRIBUTE_UNUSED
        sym->st_shndx = SHN_CR16C_NCOMMON;
     }
 
-  return TRUE;
+  return 1;
 }
 
 /* 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
@@ -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 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_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_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_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