Move C-related declarations to compile-c.h
[deliverable/binutils-gdb.git] / bfd / elf32-crx.c
index 03575f23260ab7d431664c35c2d05ec72f39d08c..fde3a588f7314e864729568409138be373802ac2 100644 (file)
@@ -1,12 +1,12 @@
 /* BFD back-end for National Semiconductor's CRX ELF
 /* BFD back-end for National Semiconductor's CRX ELF
-   Copyright 2004 Free Software Foundation, Inc.
+   Copyright (C) 2004-2018 Free Software Foundation, Inc.
    Written by Tomer Levi, NSC, Israel.
 
    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
    Written by Tomer Levi, NSC, Israel.
 
    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 "bfdlink.h"
 #include "libbfd.h"
 #include "elf-bfd.h"
 #include "bfdlink.h"
 #include "libbfd.h"
 #include "elf-bfd.h"
 
 static reloc_howto_type *elf_crx_reloc_type_lookup
   (bfd *, bfd_reloc_code_real_type);
 
 static reloc_howto_type *elf_crx_reloc_type_lookup
   (bfd *, bfd_reloc_code_real_type);
-static void elf_crx_info_to_howto
+static bfd_boolean elf_crx_info_to_howto
   (bfd *, arelent *, Elf_Internal_Rela *);
 static bfd_boolean elf32_crx_relax_delete_bytes
   (bfd *, arelent *, Elf_Internal_Rela *);
 static bfd_boolean elf32_crx_relax_delete_bytes
-  (bfd *, asection *, bfd_vma, int);
+  (struct bfd_link_info *, bfd *, asection *, bfd_vma, int);
 static bfd_reloc_status_type crx_elf_final_link_relocate
   (reloc_howto_type *, bfd *, bfd *, asection *,
    bfd_byte *, bfd_vma, bfd_vma, bfd_vma,
 static bfd_reloc_status_type crx_elf_final_link_relocate
   (reloc_howto_type *, bfd *, bfd *, asection *,
    bfd_byte *, bfd_vma, bfd_vma, bfd_vma,
@@ -38,12 +39,6 @@ static bfd_reloc_status_type crx_elf_final_link_relocate
 static bfd_boolean elf32_crx_relocate_section
   (bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
    Elf_Internal_Rela *, Elf_Internal_Sym *, asection **);
 static bfd_boolean elf32_crx_relocate_section
   (bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
    Elf_Internal_Rela *, Elf_Internal_Sym *, asection **);
-static asection * elf32_crx_gc_mark_hook
-  (asection *, struct bfd_link_info *, Elf_Internal_Rela *,
-   struct elf_link_hash_entry *, Elf_Internal_Sym *);
-static bfd_boolean elf32_crx_gc_sweep_hook
-  (bfd *, struct bfd_link_info *, asection *,
-   const Elf_Internal_Rela *);
 static bfd_boolean elf32_crx_relax_section
   (bfd *, asection *, struct bfd_link_info *, bfd_boolean *);
 static bfd_byte * elf32_crx_get_relocated_section_contents
 static bfd_boolean elf32_crx_relax_section
   (bfd *, asection *, struct bfd_link_info *, bfd_boolean *);
 static bfd_byte * elf32_crx_get_relocated_section_contents
@@ -77,15 +72,18 @@ static const struct crx_reloc_map crx_reloc_map[R_CRX_MAX] =
   {BFD_RELOC_CRX_NUM16,            R_CRX_NUM16},
   {BFD_RELOC_CRX_NUM32,            R_CRX_NUM32},
   {BFD_RELOC_CRX_IMM16,            R_CRX_IMM16},
   {BFD_RELOC_CRX_NUM16,            R_CRX_NUM16},
   {BFD_RELOC_CRX_NUM32,            R_CRX_NUM32},
   {BFD_RELOC_CRX_IMM16,            R_CRX_IMM16},
-  {BFD_RELOC_CRX_IMM32,            R_CRX_IMM32}
+  {BFD_RELOC_CRX_IMM32,            R_CRX_IMM32},
+  {BFD_RELOC_CRX_SWITCH8,   R_CRX_SWITCH8},
+  {BFD_RELOC_CRX_SWITCH16,  R_CRX_SWITCH16},
+  {BFD_RELOC_CRX_SWITCH32,  R_CRX_SWITCH32}
 };
 
 static reloc_howto_type crx_elf_howto_table[] =
 {
   HOWTO (R_CRX_NONE,           /* type */
         0,                     /* rightshift */
 };
 
 static reloc_howto_type crx_elf_howto_table[] =
 {
   HOWTO (R_CRX_NONE,           /* type */
         0,                     /* rightshift */
-        2,                     /* size */
-        32,                    /* bitsize */
+        3,                     /* size */
+        0,                     /* bitsize */
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont,/* complain_on_overflow */
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont,/* complain_on_overflow */
@@ -106,7 +104,7 @@ static reloc_howto_type crx_elf_howto_table[] =
         bfd_elf_generic_reloc, /* special_function */
         "R_CRX_REL4",          /* name */
         FALSE,                 /* partial_inplace */
         bfd_elf_generic_reloc, /* special_function */
         "R_CRX_REL4",          /* name */
         FALSE,                 /* partial_inplace */
-        0xf,                   /* src_mask */
+        0x0,                   /* src_mask */
         0xf,                   /* dst_mask */
         FALSE),                /* pcrel_offset */
 
         0xf,                   /* dst_mask */
         FALSE),                /* pcrel_offset */
 
@@ -120,7 +118,7 @@ static reloc_howto_type crx_elf_howto_table[] =
         bfd_elf_generic_reloc, /* special_function */
         "R_CRX_REL8",          /* name */
         FALSE,                 /* partial_inplace */
         bfd_elf_generic_reloc, /* special_function */
         "R_CRX_REL8",          /* name */
         FALSE,                 /* partial_inplace */
-        0xff,                  /* src_mask */
+        0x0,                   /* src_mask */
         0xff,                  /* dst_mask */
         FALSE),                /* pcrel_offset */
 
         0xff,                  /* dst_mask */
         FALSE),                /* pcrel_offset */
 
@@ -134,7 +132,7 @@ static reloc_howto_type crx_elf_howto_table[] =
         bfd_elf_generic_reloc, /* special_function */
         "R_CRX_REL8_CMP",      /* name */
         FALSE,                 /* partial_inplace */
         bfd_elf_generic_reloc, /* special_function */
         "R_CRX_REL8_CMP",      /* name */
         FALSE,                 /* partial_inplace */
-        0xff,                  /* src_mask */
+        0x0,                   /* src_mask */
         0xff,                  /* dst_mask */
         FALSE),                /* pcrel_offset */
 
         0xff,                  /* dst_mask */
         FALSE),                /* pcrel_offset */
 
@@ -148,7 +146,7 @@ static reloc_howto_type crx_elf_howto_table[] =
         bfd_elf_generic_reloc, /* special_function */
         "R_CRX_REL16",         /* name */
         FALSE,                 /* partial_inplace */
         bfd_elf_generic_reloc, /* special_function */
         "R_CRX_REL16",         /* name */
         FALSE,                 /* partial_inplace */
-        0xffff,                /* src_mask */
+        0x0,                   /* src_mask */
         0xffff,                /* dst_mask */
         FALSE),                /* pcrel_offset */
 
         0xffff,                /* dst_mask */
         FALSE),                /* pcrel_offset */
 
@@ -162,7 +160,7 @@ static reloc_howto_type crx_elf_howto_table[] =
         bfd_elf_generic_reloc, /* special_function */
         "R_CRX_REL24",         /* name */
         FALSE,                 /* partial_inplace */
         bfd_elf_generic_reloc, /* special_function */
         "R_CRX_REL24",         /* name */
         FALSE,                 /* partial_inplace */
-        0xffffff,              /* src_mask */
+        0x0,                   /* src_mask */
         0xffffff,              /* dst_mask */
         FALSE),                /* pcrel_offset */
 
         0xffffff,              /* dst_mask */
         FALSE),                /* pcrel_offset */
 
@@ -176,7 +174,7 @@ static reloc_howto_type crx_elf_howto_table[] =
         bfd_elf_generic_reloc, /* special_function */
         "R_CRX_REL32",         /* name */
         FALSE,                 /* partial_inplace */
         bfd_elf_generic_reloc, /* special_function */
         "R_CRX_REL32",         /* name */
         FALSE,                 /* partial_inplace */
-        0xffffffff,            /* src_mask */
+        0x0,                   /* src_mask */
         0xffffffff,            /* dst_mask */
         FALSE),                /* pcrel_offset */
 
         0xffffffff,            /* dst_mask */
         FALSE),                /* pcrel_offset */
 
@@ -190,7 +188,7 @@ static reloc_howto_type crx_elf_howto_table[] =
         bfd_elf_generic_reloc, /* special_function */
         "R_CRX_REGREL12",      /* name */
         FALSE,                 /* partial_inplace */
         bfd_elf_generic_reloc, /* special_function */
         "R_CRX_REGREL12",      /* name */
         FALSE,                 /* partial_inplace */
-        0xfff,                 /* src_mask */
+        0x0,                   /* src_mask */
         0xfff,                 /* dst_mask */
         FALSE),                /* pcrel_offset */
 
         0xfff,                 /* dst_mask */
         FALSE),                /* pcrel_offset */
 
@@ -204,7 +202,7 @@ static reloc_howto_type crx_elf_howto_table[] =
         bfd_elf_generic_reloc, /* special_function */
         "R_CRX_REGREL22",      /* name */
         FALSE,                 /* partial_inplace */
         bfd_elf_generic_reloc, /* special_function */
         "R_CRX_REGREL22",      /* name */
         FALSE,                 /* partial_inplace */
-        0x3fffff,              /* src_mask */
+        0x0,                   /* src_mask */
         0x3fffff,              /* dst_mask */
         FALSE),                /* pcrel_offset */
 
         0x3fffff,              /* dst_mask */
         FALSE),                /* pcrel_offset */
 
@@ -218,7 +216,7 @@ static reloc_howto_type crx_elf_howto_table[] =
         bfd_elf_generic_reloc, /* special_function */
         "R_CRX_REGREL28",      /* name */
         FALSE,                 /* partial_inplace */
         bfd_elf_generic_reloc, /* special_function */
         "R_CRX_REGREL28",      /* name */
         FALSE,                 /* partial_inplace */
-        0xfffffff,             /* src_mask */
+        0x0,                   /* src_mask */
         0xfffffff,             /* dst_mask */
         FALSE),                /* pcrel_offset */
 
         0xfffffff,             /* dst_mask */
         FALSE),                /* pcrel_offset */
 
@@ -232,7 +230,7 @@ static reloc_howto_type crx_elf_howto_table[] =
         bfd_elf_generic_reloc, /* special_function */
         "R_CRX_REGREL32",      /* name */
         FALSE,                 /* partial_inplace */
         bfd_elf_generic_reloc, /* special_function */
         "R_CRX_REGREL32",      /* name */
         FALSE,                 /* partial_inplace */
-        0xffffffff,            /* src_mask */
+        0x0,                   /* src_mask */
         0xffffffff,            /* dst_mask */
         FALSE),                /* pcrel_offset */
 
         0xffffffff,            /* dst_mask */
         FALSE),                /* pcrel_offset */
 
@@ -246,7 +244,7 @@ static reloc_howto_type crx_elf_howto_table[] =
         bfd_elf_generic_reloc, /* special_function */
         "R_CRX_ABS16",         /* name */
         FALSE,                 /* partial_inplace */
         bfd_elf_generic_reloc, /* special_function */
         "R_CRX_ABS16",         /* name */
         FALSE,                 /* partial_inplace */
-        0xffff,                /* src_mask */
+        0x0,                   /* src_mask */
         0xffff,                /* dst_mask */
         FALSE),                /* pcrel_offset */
 
         0xffff,                /* dst_mask */
         FALSE),                /* pcrel_offset */
 
@@ -260,7 +258,7 @@ static reloc_howto_type crx_elf_howto_table[] =
         bfd_elf_generic_reloc, /* special_function */
         "R_CRX_ABS32",         /* name */
         FALSE,                 /* partial_inplace */
         bfd_elf_generic_reloc, /* special_function */
         "R_CRX_ABS32",         /* name */
         FALSE,                 /* partial_inplace */
-        0xffffffff,            /* src_mask */
+        0x0,                   /* src_mask */
         0xffffffff,            /* dst_mask */
         FALSE),                /* pcrel_offset */
 
         0xffffffff,            /* dst_mask */
         FALSE),                /* pcrel_offset */
 
@@ -274,7 +272,7 @@ static reloc_howto_type crx_elf_howto_table[] =
         bfd_elf_generic_reloc, /* special_function */
         "R_CRX_NUM8",          /* name */
         FALSE,                 /* partial_inplace */
         bfd_elf_generic_reloc, /* special_function */
         "R_CRX_NUM8",          /* name */
         FALSE,                 /* partial_inplace */
-        0xff,                  /* src_mask */
+        0x0,                   /* src_mask */
         0xff,                  /* dst_mask */
         FALSE),                /* pcrel_offset */
 
         0xff,                  /* dst_mask */
         FALSE),                /* pcrel_offset */
 
@@ -288,7 +286,7 @@ static reloc_howto_type crx_elf_howto_table[] =
         bfd_elf_generic_reloc, /* special_function */
         "R_CRX_NUM16",         /* name */
         FALSE,                 /* partial_inplace */
         bfd_elf_generic_reloc, /* special_function */
         "R_CRX_NUM16",         /* name */
         FALSE,                 /* partial_inplace */
-        0xffff,                /* src_mask */
+        0x0,                   /* src_mask */
         0xffff,                /* dst_mask */
         FALSE),                /* pcrel_offset */
 
         0xffff,                /* dst_mask */
         FALSE),                /* pcrel_offset */
 
@@ -302,7 +300,7 @@ static reloc_howto_type crx_elf_howto_table[] =
         bfd_elf_generic_reloc, /* special_function */
         "R_CRX_NUM32",         /* name */
         FALSE,                 /* partial_inplace */
         bfd_elf_generic_reloc, /* special_function */
         "R_CRX_NUM32",         /* name */
         FALSE,                 /* partial_inplace */
-        0xffffffff,            /* src_mask */
+        0x0,                   /* src_mask */
         0xffffffff,            /* dst_mask */
         FALSE),                /* pcrel_offset */
 
         0xffffffff,            /* dst_mask */
         FALSE),                /* pcrel_offset */
 
@@ -316,7 +314,7 @@ static reloc_howto_type crx_elf_howto_table[] =
         bfd_elf_generic_reloc, /* special_function */
         "R_CRX_IMM16",         /* name */
         FALSE,                 /* partial_inplace */
         bfd_elf_generic_reloc, /* special_function */
         "R_CRX_IMM16",         /* name */
         FALSE,                 /* partial_inplace */
-        0xffff,                /* src_mask */
+        0x0,                   /* src_mask */
         0xffff,                /* dst_mask */
         FALSE),                /* pcrel_offset */
 
         0xffff,                /* dst_mask */
         FALSE),                /* pcrel_offset */
 
@@ -330,9 +328,60 @@ static reloc_howto_type crx_elf_howto_table[] =
         bfd_elf_generic_reloc, /* special_function */
         "R_CRX_IMM32",         /* name */
         FALSE,                 /* partial_inplace */
         bfd_elf_generic_reloc, /* special_function */
         "R_CRX_IMM32",         /* name */
         FALSE,                 /* partial_inplace */
-        0xffffffff,            /* src_mask */
+        0x0,                   /* src_mask */
         0xffffffff,            /* dst_mask */
         0xffffffff,            /* dst_mask */
-        FALSE)                 /* pcrel_offset */
+        FALSE),                /* pcrel_offset */
+
+  /* An 8 bit switch table entry.  This is generated for an expression
+     such as ``.byte L1 - L2''.  The offset holds the difference
+     between the reloc address and L2.  */
+  HOWTO (R_CRX_SWITCH8,                /* type */
+        0,                     /* rightshift */
+        0,                     /* size (0 = byte, 1 = short, 2 = long) */
+        8,                     /* bitsize */
+        FALSE,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_unsigned, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_CRX_SWITCH8",       /* name */
+        FALSE,                 /* partial_inplace */
+        0x0,                   /* src_mask */
+        0xff,                  /* dst_mask */
+        TRUE),                 /* pcrel_offset */
+
+  /* A 16 bit switch table entry.  This is generated for an expression
+     such as ``.word L1 - L2''.  The offset holds the difference
+     between the reloc address and L2.  */
+  HOWTO (R_CRX_SWITCH16,       /* type */
+        0,                     /* rightshift */
+        1,                     /* size (0 = byte, 1 = short, 2 = long) */
+        16,                    /* bitsize */
+        FALSE,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_unsigned, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_CRX_SWITCH16",      /* name */
+        FALSE,                 /* partial_inplace */
+        0x0,                   /* src_mask */
+        0xffff,                /* dst_mask */
+        TRUE),                 /* pcrel_offset */
+
+  /* A 32 bit switch table entry.  This is generated for an expression
+     such as ``.long L1 - L2''.  The offset holds the difference
+     between the reloc address and L2.  */
+  HOWTO (R_CRX_SWITCH32,       /* type */
+        0,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        32,                    /* bitsize */
+        FALSE,                 /* pc_relative */
+        0,                     /* bitpos */
+        complain_overflow_unsigned, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_CRX_SWITCH32",      /* name */
+        FALSE,                 /* partial_inplace */
+        0x0,                   /* src_mask */
+        0xffffffff,            /* dst_mask */
+        TRUE)                  /* pcrel_offset */
 };
 
 /* Retrieve a howto ptr using a BFD reloc_code.  */
 };
 
 /* Retrieve a howto ptr using a BFD reloc_code.  */
@@ -351,15 +400,39 @@ elf_crx_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
   return 0;
 }
 
   return 0;
 }
 
+static reloc_howto_type *
+elf_crx_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+                          const char *r_name)
+{
+  unsigned int i;
+
+  for (i = 0;
+       i < sizeof (crx_elf_howto_table) / sizeof (crx_elf_howto_table[0]);
+       i++)
+    if (crx_elf_howto_table[i].name != NULL
+       && strcasecmp (crx_elf_howto_table[i].name, r_name) == 0)
+      return &crx_elf_howto_table[i];
+
+  return NULL;
+}
+
 /* Retrieve a howto ptr using an internal relocation entry.  */
 
 /* Retrieve a howto ptr using an internal relocation entry.  */
 
-static void
-elf_crx_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED, arelent *cache_ptr,
+static bfd_boolean
+elf_crx_info_to_howto (bfd *abfd, arelent *cache_ptr,
                       Elf_Internal_Rela *dst)
 {
   unsigned int r_type = ELF32_R_TYPE (dst->r_info);
                       Elf_Internal_Rela *dst)
 {
   unsigned int r_type = ELF32_R_TYPE (dst->r_info);
-  BFD_ASSERT (r_type < (unsigned int) R_CRX_MAX);
+  if (r_type >= R_CRX_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 = &crx_elf_howto_table[r_type];
   cache_ptr->howto = &crx_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.  */
@@ -406,6 +479,13 @@ crx_elf_final_link_relocate (reloc_howto_type *howto, bfd *input_bfd,
        return bfd_reloc_ok;
        break;
 
        return bfd_reloc_ok;
        break;
 
+     case R_CRX_SWITCH8:
+     case R_CRX_SWITCH16:
+     case R_CRX_SWITCH32:
+       /* We only care about the addend, where the difference between
+         expressions is kept.  */
+       Rvalue = 0;
+
      default:
        break;
     }
      default:
        break;
     }
@@ -483,7 +563,7 @@ crx_elf_final_link_relocate (reloc_howto_type *howto, bfd *input_bfd,
         Rvalue |= (((bfd_get_16 (input_bfd, hit_data) << 16) |
                      bfd_get_16 (input_bfd, hit_data + 2)) & ~howto->dst_mask);
 
         Rvalue |= (((bfd_get_16 (input_bfd, hit_data) << 16) |
                      bfd_get_16 (input_bfd, hit_data + 2)) & ~howto->dst_mask);
 
-       if (r_type == R_CRX_NUM32)
+       if (r_type == R_CRX_NUM32 || r_type == R_CRX_SWITCH32)
         /* Relocation on DATA is purely little-endian, that is, for a
            multi-byte datum, the lowest address in memory contains the
            little end of the datum, that is, the least significant byte.
         /* Relocation on DATA is purely little-endian, that is, for a
            multi-byte datum, the lowest address in memory contains the
            little end of the datum, that is, the least significant byte.
@@ -512,29 +592,25 @@ crx_elf_final_link_relocate (reloc_howto_type *howto, bfd *input_bfd,
 /* Delete some bytes from a section while relaxing.  */
 
 static bfd_boolean
 /* Delete some bytes from a section while relaxing.  */
 
 static bfd_boolean
-elf32_crx_relax_delete_bytes (bfd *abfd, asection *sec,
-                             bfd_vma addr, int count)
+elf32_crx_relax_delete_bytes (struct bfd_link_info *link_info, bfd *abfd,
+                             asection *sec, bfd_vma addr, int count)
 {
   Elf_Internal_Shdr *symtab_hdr;
   unsigned int sec_shndx;
   bfd_byte *contents;
   Elf_Internal_Rela *irel, *irelend;
 {
   Elf_Internal_Shdr *symtab_hdr;
   unsigned int sec_shndx;
   bfd_byte *contents;
   Elf_Internal_Rela *irel, *irelend;
-  Elf_Internal_Rela *irelalign;
   bfd_vma toaddr;
   Elf_Internal_Sym *isym;
   Elf_Internal_Sym *isymend;
   struct elf_link_hash_entry **sym_hashes;
   struct elf_link_hash_entry **end_hashes;
   bfd_vma toaddr;
   Elf_Internal_Sym *isym;
   Elf_Internal_Sym *isymend;
   struct elf_link_hash_entry **sym_hashes;
   struct elf_link_hash_entry **end_hashes;
+  struct elf_link_hash_entry **start_hashes;
   unsigned int symcount;
 
   sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
 
   contents = elf_section_data (sec)->this_hdr.contents;
 
   unsigned int symcount;
 
   sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
 
   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;
@@ -562,19 +638,77 @@ elf32_crx_relax_delete_bytes (bfd *abfd, asection *sec,
       if (isym->st_shndx == sec_shndx
          && isym->st_value > addr
          && isym->st_value < toaddr)
       if (isym->st_shndx == sec_shndx
          && isym->st_value > addr
          && isym->st_value < toaddr)
-       isym->st_value -= count;
+       {
+         /* Adjust the addend of SWITCH relocations in this section,
+            which reference this local symbol.  */
+         for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++)
+           {
+             unsigned long r_symndx;
+             Elf_Internal_Sym *rsym;
+             bfd_vma addsym, subsym;
+
+             /* Skip if not a SWITCH relocation.  */
+             if (ELF32_R_TYPE (irel->r_info) != (int) R_CRX_SWITCH8
+                 && ELF32_R_TYPE (irel->r_info) != (int) R_CRX_SWITCH16
+                 && ELF32_R_TYPE (irel->r_info) != (int) R_CRX_SWITCH32)
+                 continue;
+
+             r_symndx = ELF32_R_SYM (irel->r_info);
+             rsym = (Elf_Internal_Sym *) symtab_hdr->contents + r_symndx;
+
+             /* Skip if not the local adjusted symbol.  */
+             if (rsym != isym)
+               continue;
+
+             addsym = isym->st_value;
+             subsym = addsym - irel->r_addend;
+
+             /* Fix the addend only when -->> (addsym > addr >= subsym).  */
+             if (subsym <= addr)
+               irel->r_addend -= count;
+             else
+               continue;
+           }
+
+         isym->st_value -= count;
+       }
     }
 
   /* Now adjust the global symbols defined in this section.  */
   symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
              - symtab_hdr->sh_info);
     }
 
   /* Now adjust the global symbols defined in this section.  */
   symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
              - symtab_hdr->sh_info);
-  sym_hashes = elf_sym_hashes (abfd);
+  sym_hashes = start_hashes = elf_sym_hashes (abfd);
   end_hashes = sym_hashes + symcount;
 
   for (; sym_hashes < end_hashes; sym_hashes++)
     {
       struct elf_link_hash_entry *sym_hash = *sym_hashes;
 
   end_hashes = sym_hashes + symcount;
 
   for (; sym_hashes < end_hashes; sym_hashes++)
     {
       struct elf_link_hash_entry *sym_hash = *sym_hashes;
 
+      /* The '--wrap SYMBOL' option is causing a pain when the object file,
+        containing the definition of __wrap_SYMBOL, includes a direct
+        call to SYMBOL as well. Since both __wrap_SYMBOL and SYMBOL reference
+        the same symbol (which is __wrap_SYMBOL), but still exist as two
+        different symbols in 'sym_hashes', we don't want to adjust
+        the global symbol __wrap_SYMBOL twice.
+        This check is only relevant when symbols are being wrapped.  */
+      if (link_info->wrap_hash != NULL)
+       {
+         struct elf_link_hash_entry **cur_sym_hashes;
+
+         /* Loop only over the symbols whom been already checked.  */
+         for (cur_sym_hashes = start_hashes; cur_sym_hashes < sym_hashes;
+              cur_sym_hashes++)
+           {
+             /* If the current symbol is identical to 'sym_hash', that means
+                the symbol was already adjusted (or at least checked).  */
+             if (*cur_sym_hashes == sym_hash)
+               break;
+           }
+         /* Don't adjust the symbol again.  */
+         if (cur_sym_hashes < sym_hashes)
+           continue;
+       }
+
       if ((sym_hash->root.type == bfd_link_hash_defined
           || sym_hash->root.type == bfd_link_hash_defweak)
          && sym_hash->root.u.def.section == sec
       if ((sym_hash->root.type == bfd_link_hash_defined
           || sym_hash->root.type == bfd_link_hash_defweak)
          && sym_hash->root.u.def.section == sec
@@ -627,7 +761,7 @@ elf32_crx_get_relocated_section_contents (bfd *output_bfd,
       bfd_size_type amt;
 
       internal_relocs = (_bfd_elf_link_read_relocs
       bfd_size_type amt;
 
       internal_relocs = (_bfd_elf_link_read_relocs
-                        (input_bfd, input_section, (PTR) NULL,
+                        (input_bfd, input_section, NULL,
                          (Elf_Internal_Rela *) NULL, FALSE));
       if (internal_relocs == NULL)
        goto error_return;
                          (Elf_Internal_Rela *) NULL, FALSE));
       if (internal_relocs == NULL)
        goto error_return;
@@ -707,9 +841,6 @@ elf32_crx_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
   struct elf_link_hash_entry **sym_hashes;
   Elf_Internal_Rela *rel, *relend;
 
   struct elf_link_hash_entry **sym_hashes;
   Elf_Internal_Rela *rel, *relend;
 
-  if (info->relocatable)
-    return TRUE;
-
   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
   sym_hashes = elf_sym_hashes (input_bfd);
 
   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
   sym_hashes = elf_sym_hashes (input_bfd);
 
@@ -741,14 +872,21 @@ elf32_crx_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
        }
       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))
+       continue;
+
       r = crx_elf_final_link_relocate (howto, input_bfd, output_bfd,
                                        input_section,
                                        contents, rel->r_offset,
       r = crx_elf_final_link_relocate (howto, input_bfd, output_bfd,
                                        input_section,
                                        contents, rel->r_offset,
@@ -773,17 +911,14 @@ elf32_crx_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
          switch (r)
            {
             case bfd_reloc_overflow:
          switch (r)
            {
             case bfd_reloc_overflow:
-              if (!((*info->callbacks->reloc_overflow)
-                    (info, 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:
@@ -803,10 +938,8 @@ elf32_crx_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
               /* 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;
            }
        }
@@ -842,7 +975,7 @@ elf32_crx_relax_section (bfd *abfd, asection *sec,
   /* 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)
       || (sec->flags & SEC_RELOC) == 0
       || sec->reloc_count == 0
       || (sec->flags & SEC_CODE) == 0)
@@ -852,7 +985,7 @@ elf32_crx_relax_section (bfd *abfd, asection *sec,
 
   /* Get a copy of the native relocations.  */
   internal_relocs = (_bfd_elf_link_read_relocs
 
   /* 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;
@@ -983,7 +1116,7 @@ elf32_crx_relax_section (bfd *abfd, asection *sec,
                                           R_CRX_REL16);
 
              /* Delete two bytes of data.  */
                                           R_CRX_REL16);
 
              /* Delete two bytes of data.  */
-             if (!elf32_crx_relax_delete_bytes (abfd, sec,
+             if (!elf32_crx_relax_delete_bytes (link_info, abfd, sec,
                                                   irel->r_offset + 2, 2))
                goto error_return;
 
                                                   irel->r_offset + 2, 2))
                goto error_return;
 
@@ -1028,7 +1161,7 @@ elf32_crx_relax_section (bfd *abfd, asection *sec,
                                           R_CRX_REL8);
 
              /* Delete two bytes of data.  */
                                           R_CRX_REL8);
 
              /* Delete two bytes of data.  */
-             if (!elf32_crx_relax_delete_bytes (abfd, sec,
+             if (!elf32_crx_relax_delete_bytes (link_info, abfd, sec,
                                                   irel->r_offset + 2, 2))
                goto error_return;
 
                                                   irel->r_offset + 2, 2))
                goto error_return;
 
@@ -1062,7 +1195,9 @@ elf32_crx_relax_section (bfd *abfd, asection *sec,
              /* Verify it's a 'cmp&branch' opcode.  */
              if ((code & 0xfff0) != 0x3180 && (code & 0xfff0) != 0x3190
               && (code & 0xfff0) != 0x31a0 && (code & 0xfff0) != 0x31c0
              /* Verify it's a 'cmp&branch' opcode.  */
              if ((code & 0xfff0) != 0x3180 && (code & 0xfff0) != 0x3190
               && (code & 0xfff0) != 0x31a0 && (code & 0xfff0) != 0x31c0
-              && (code & 0xfff0) != 0x31d0 && (code & 0xfff0) != 0x31e0)
+              && (code & 0xfff0) != 0x31d0 && (code & 0xfff0) != 0x31e0
+              /* Or a Co-processor branch ('bcop').  */
+              && (code & 0xfff0) != 0x3010 && (code & 0xfff0) != 0x3110)
                continue;
 
              /* Note that we've changed the relocs, section contents, etc.  */
                continue;
 
              /* Note that we've changed the relocs, section contents, etc.  */
@@ -1078,7 +1213,7 @@ elf32_crx_relax_section (bfd *abfd, asection *sec,
                                           R_CRX_REL8_CMP);
 
              /* Delete two bytes of data.  */
                                           R_CRX_REL8_CMP);
 
              /* Delete two bytes of data.  */
-             if (!elf32_crx_relax_delete_bytes (abfd, sec,
+             if (!elf32_crx_relax_delete_bytes (link_info, abfd, sec,
                                                   irel->r_offset + 4, 2))
                goto error_return;
 
                                                   irel->r_offset + 4, 2))
                goto error_return;
 
@@ -1119,7 +1254,7 @@ elf32_crx_relax_section (bfd *abfd, asection *sec,
                                           R_CRX_IMM16);
 
              /* Delete two bytes of data.  */
                                           R_CRX_IMM16);
 
              /* Delete two bytes of data.  */
-             if (!elf32_crx_relax_delete_bytes (abfd, sec,
+             if (!elf32_crx_relax_delete_bytes (link_info, abfd, sec,
                                                   irel->r_offset + 2, 2))
                goto error_return;
 
                                                   irel->r_offset + 2, 2))
                goto error_return;
 
@@ -1174,44 +1309,8 @@ elf32_crx_relax_section (bfd *abfd, asection *sec,
   return FALSE;
 }
 
   return FALSE;
 }
 
-static asection *
-elf32_crx_gc_mark_hook (asection *sec,
-                       struct bfd_link_info *info ATTRIBUTE_UNUSED,
-                       Elf_Internal_Rela *rel ATTRIBUTE_UNUSED,
-                       struct elf_link_hash_entry *h,
-                       Elf_Internal_Sym *sym)
-{
-  if (h == NULL)
-    return bfd_section_from_elf_index (sec->owner, sym->st_shndx);
-
-  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:
-      return NULL;
-    }
-}
-
-/* Update the got entry reference counts for the section being removed.  */
-
-static bfd_boolean
-elf32_crx_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;
-}
-
 /* Definitions for setting CRX target vector.  */
 /* Definitions for setting CRX target vector.  */
-#define TARGET_LITTLE_SYM              bfd_elf32_crx_vec
+#define TARGET_LITTLE_SYM              crx_elf32_vec
 #define TARGET_LITTLE_NAME             "elf32-crx"
 #define ELF_ARCH                       bfd_arch_crx
 #define ELF_MACHINE_CODE               EM_CRX
 #define TARGET_LITTLE_NAME             "elf32-crx"
 #define ELF_ARCH                       bfd_arch_crx
 #define ELF_MACHINE_CODE               EM_CRX
@@ -1219,14 +1318,14 @@ elf32_crx_gc_sweep_hook (bfd *abfd ATTRIBUTE_UNUSED,
 #define elf_symbol_leading_char                '_'
 
 #define bfd_elf32_bfd_reloc_type_lookup        elf_crx_reloc_type_lookup
 #define elf_symbol_leading_char                '_'
 
 #define bfd_elf32_bfd_reloc_type_lookup        elf_crx_reloc_type_lookup
+#define bfd_elf32_bfd_reloc_name_lookup \
+                                       elf_crx_reloc_name_lookup
 #define elf_info_to_howto              elf_crx_info_to_howto
 #define elf_info_to_howto              elf_crx_info_to_howto
-#define elf_info_to_howto_rel          0
+#define elf_info_to_howto_rel          NULL
 #define elf_backend_relocate_section   elf32_crx_relocate_section
 #define bfd_elf32_bfd_relax_section    elf32_crx_relax_section
 #define bfd_elf32_bfd_get_relocated_section_contents \
                                elf32_crx_get_relocated_section_contents
 #define elf_backend_relocate_section   elf32_crx_relocate_section
 #define bfd_elf32_bfd_relax_section    elf32_crx_relax_section
 #define bfd_elf32_bfd_get_relocated_section_contents \
                                elf32_crx_get_relocated_section_contents
-#define elf_backend_gc_mark_hook        elf32_crx_gc_mark_hook
-#define elf_backend_gc_sweep_hook       elf32_crx_gc_sweep_hook
 #define elf_backend_can_gc_sections     1
 #define elf_backend_rela_normal                1
 
 #define elf_backend_can_gc_sections     1
 #define elf_backend_rela_normal                1
 
This page took 0.032391 seconds and 4 git commands to generate.