3a14e4
diff -rup binutils.orig/bfd/elf-bfd.h binutils-2.27/bfd/elf-bfd.h
3a14e4
--- binutils.orig/bfd/elf-bfd.h	2020-02-12 14:41:48.890875908 +0000
3a14e4
+++ binutils-2.27/bfd/elf-bfd.h	2020-02-12 14:41:58.777803052 +0000
3a14e4
@@ -1367,6 +1367,19 @@ struct elf_backend_data
3a14e4
   /* Opcode representing no unwind.  */
3a14e4
   int (*cant_unwind_opcode) (struct bfd_link_info *);
3a14e4
 
3a14e4
+  /* Called when a section has extra reloc sections.  */
3a14e4
+  bfd_boolean (*init_secondary_reloc_section) (bfd *, Elf_Internal_Shdr *, const char *, unsigned int);
3a14e4
+
3a14e4
+  /* Called when after loading the normal relocs for a section.  */
3a14e4
+  bfd_boolean (*slurp_secondary_relocs) (bfd *, asection *, asymbol **);
3a14e4
+
3a14e4
+  /* Called after writing the normal relocs for a section.  */
3a14e4
+  bfd_boolean (*write_secondary_relocs) (bfd *, asection *);
3a14e4
+
3a14e4
+  /* Called to return the value to set in the ST_SHNDX field of an ELF symbol
3a14e4
+     from an iternal symbol which does not map to any known section.  */
3a14e4
+  unsigned int (*symbol_section_index) (bfd *, elf_symbol_type *);
3a14e4
+  
3a14e4
   /* This is non-zero if static TLS segments require a special alignment.  */
3a14e4
   unsigned static_tls_alignment;
3a14e4
 
3a14e4
@@ -2535,6 +2548,19 @@ extern bfd_vma elf64_r_sym (bfd_vma);
3a14e4
 extern bfd_vma elf32_r_info (bfd_vma, bfd_vma);
3a14e4
 extern bfd_vma elf32_r_sym (bfd_vma);
3a14e4
 
3a14e4
+
3a14e4
+extern bfd_boolean _bfd_elf_init_secondary_reloc_section
3a14e4
+  (bfd *, Elf_Internal_Shdr *, const char *, unsigned int);
3a14e4
+extern bfd_boolean _bfd_elf_slurp_secondary_reloc_section
3a14e4
+  (bfd *, asection *, asymbol **);
3a14e4
+extern bfd_boolean _bfd_elf_copy_special_section_fields
3a14e4
+  (const bfd *, bfd *, const Elf_Internal_Shdr *, Elf_Internal_Shdr *);
3a14e4
+extern bfd_boolean _bfd_elf_write_secondary_reloc_section
3a14e4
+  (bfd *, asection *);
3a14e4
+extern unsigned int _bfd_elf_symbol_section_index
3a14e4
+  (bfd *, elf_symbol_type *);
3a14e4
+
3a14e4
+
3a14e4
 /* Large common section.  */
3a14e4
 extern asection _bfd_elf_large_com_section;
3a14e4
 
3a14e4
diff -rup binutils.orig/bfd/elf.c binutils-2.27/bfd/elf.c
3a14e4
--- binutils.orig/bfd/elf.c	2020-02-12 14:41:48.893875886 +0000
3a14e4
+++ binutils-2.27/bfd/elf.c	2020-02-12 14:41:58.778803044 +0000
3a14e4
@@ -1490,7 +1490,7 @@ _bfd_elf_copy_private_bfd_data (bfd *ibf
3a14e4
 	  /* Final attempt.  Call the backend copy function
3a14e4
 	     with a NULL input section.  */
3a14e4
 	  if (bed->elf_backend_copy_special_section_fields != NULL)
3a14e4
-	    bed->elf_backend_copy_special_section_fields (ibfd, obfd, NULL, oheader);
3a14e4
+	    (void) bed->elf_backend_copy_special_section_fields (ibfd, obfd, NULL, oheader);
3a14e4
 	}
3a14e4
     }
3a14e4
 
3a14e4
@@ -2329,11 +2329,14 @@ bfd_section_from_shdr (bfd *abfd, unsign
3a14e4
 	   sections.  */
3a14e4
 	if (*p_hdr != NULL)
3a14e4
 	  {
3a14e4
-	    _bfd_error_handler
3a14e4
-	      /* xgettext:c-format */
3a14e4
-	      (_("%B: warning: multiple relocation sections for section %A \
3a14e4
-found - ignoring all but the first"),
3a14e4
-	       abfd, target_sect);
3a14e4
+	    if (bed->init_secondary_reloc_section == NULL
3a14e4
+		|| ! bed->init_secondary_reloc_section (abfd, hdr, name, shindex))
3a14e4
+	      {
3a14e4
+		_bfd_error_handler
3a14e4
+		  /* xgettext:c-format */
3a14e4
+		  (_("%pB: warning: secondary relocation section '%s' for section %pA found - ignoring"),
3a14e4
+		   abfd, name, target_sect);
3a14e4
+	      }
3a14e4
 	    goto success;
3a14e4
 	  }
3a14e4
 	hdr2 = (Elf_Internal_Shdr *) bfd_alloc (abfd, sizeof (*hdr2));
3a14e4
@@ -7607,9 +7610,20 @@ error_return:
3a14e4
 		  if (elf_symtab_shndx_list (abfd))
3a14e4
 		    shndx = elf_symtab_shndx_list (abfd)->ndx;
3a14e4
 		  break;
3a14e4
-		default:
3a14e4
+		case SHN_COMMON:
3a14e4
+		case SHN_ABS:
3a14e4
 		  shndx = SHN_ABS;
3a14e4
 		  break;
3a14e4
+		default:
3a14e4
+		  if (bed->symbol_section_index)
3a14e4
+		    shndx = bed->symbol_section_index (abfd, type_ptr);
3a14e4
+		  else
3a14e4
+		    {
3a14e4
+		      _bfd_error_handler (_("%pB: Unable to handle section index %x in ELF symbol.  Using ABS instead. (%x)"),
3a14e4
+					  abfd, shndx, SHN_COMMON);
3a14e4
+		      shndx = SHN_ABS;
3a14e4
+		    }
3a14e4
+		  break;
3a14e4
 		}
3a14e4
 	    }
3a14e4
 	  else
3a14e4
@@ -11056,3 +11070,354 @@ _bfd_elf_maybe_function_sym (const asymb
3a14e4
     size = 1;
3a14e4
   return size;
3a14e4
 }
3a14e4
+
3a14e4
+/* Set to non-zero to enable some debug messages.  */
3a14e4
+#define DEBUG_SECONDARY_RELOCS	 0
3a14e4
+
3a14e4
+/* An internal-to-the-bfd-library only section type
3a14e4
+   used to indicate a cached secondary reloc section.  */
3a14e4
+#define SHT_SECONDARY_RELOC	 (SHT_LOOS + SHT_RELA)
3a14e4
+
3a14e4
+/* Create a BFD section to hold a secondary reloc section.  */
3a14e4
+
3a14e4
+bfd_boolean
3a14e4
+_bfd_elf_init_secondary_reloc_section (bfd * abfd,
3a14e4
+				       Elf_Internal_Shdr *hdr,
3a14e4
+				       const char * name,
3a14e4
+				       unsigned int shindex)
3a14e4
+{
3a14e4
+  /* We only support RELA secondary relocs.  */
3a14e4
+  if (hdr->sh_type != SHT_RELA)
3a14e4
+    return FALSE;
3a14e4
+
3a14e4
+#if DEBUG_SECONDARY_RELOCS
3a14e4
+  fprintf (stderr, "secondary reloc section %s encountered\n", name);
3a14e4
+#endif
3a14e4
+  hdr->sh_type = SHT_SECONDARY_RELOC;
3a14e4
+  return _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex);
3a14e4
+}
3a14e4
+
3a14e4
+/* Read in any secondary relocs associated with SEC.  */
3a14e4
+
3a14e4
+bfd_boolean
3a14e4
+_bfd_elf_slurp_secondary_reloc_section (bfd *      abfd,
3a14e4
+					asection * sec,
3a14e4
+					asymbol ** symbols)
3a14e4
+{
3a14e4
+  const struct elf_backend_data * const ebd = get_elf_backend_data (abfd);
3a14e4
+  asection * relsec;
3a14e4
+  bfd_boolean result = TRUE;
3a14e4
+  bfd_vma (*r_sym) (bfd_vma);
3a14e4
+
3a14e4
+
3a14e4
+#ifdef BFD64
3a14e4
+  if (bfd_arch_bits_per_address (abfd) != 32)
3a14e4
+    r_sym = elf64_r_sym;
3a14e4
+  else
3a14e4
+#endif
3a14e4
+    r_sym = elf32_r_sym;
3a14e4
+  
3a14e4
+  /* Discover if there are any secondary reloc sections
3a14e4
+     associated with SEC.  */
3a14e4
+  for (relsec = abfd->sections; relsec != NULL; relsec = relsec->next)
3a14e4
+    {
3a14e4
+      Elf_Internal_Shdr * hdr = & elf_section_data (relsec)->this_hdr;
3a14e4
+
3a14e4
+      if (hdr->sh_type == SHT_SECONDARY_RELOC
3a14e4
+	  && hdr->sh_info == (unsigned) elf_section_data (sec)->this_idx)
3a14e4
+	{
3a14e4
+	  bfd_byte * native_relocs;
3a14e4
+	  bfd_byte * native_reloc;
3a14e4
+	  arelent * internal_relocs;
3a14e4
+	  arelent * internal_reloc;
3a14e4
+	  unsigned int i;
3a14e4
+	  unsigned int entsize;
3a14e4
+	  unsigned int symcount;
3a14e4
+	  unsigned int reloc_count;
3a14e4
+
3a14e4
+#if DEBUG_SECONDARY_RELOCS
3a14e4
+	  fprintf (stderr, "read secondary relocs for %s from %s\n", sec->name, relsec->name);
3a14e4
+#endif
3a14e4
+	  entsize = hdr->sh_entsize;
3a14e4
+
3a14e4
+	  native_relocs = bfd_malloc (hdr->sh_size);
3a14e4
+	  if (native_relocs == NULL)
3a14e4
+	    {
3a14e4
+	      result = FALSE;
3a14e4
+	      continue;
3a14e4
+	    }
3a14e4
+
3a14e4
+	  reloc_count = NUM_SHDR_ENTRIES (hdr);
3a14e4
+	  internal_relocs = (arelent *) bfd_alloc2 (abfd, reloc_count, sizeof (arelent));
3a14e4
+	  if (internal_relocs == NULL)
3a14e4
+	    {
3a14e4
+	      free (native_relocs);
3a14e4
+	      result = FALSE;
3a14e4
+	      continue;
3a14e4
+	    }
3a14e4
+
3a14e4
+	  if (bfd_seek (abfd, hdr->sh_offset, SEEK_SET) != 0
3a14e4
+	      || (bfd_bread (native_relocs, hdr->sh_size, abfd) != hdr->sh_size))
3a14e4
+	    {
3a14e4
+	      free (native_relocs);
3a14e4
+	      free (internal_relocs);
3a14e4
+	      result = FALSE;
3a14e4
+	      continue;
3a14e4
+	    }
3a14e4
+
3a14e4
+	  symcount = bfd_get_symcount (abfd);
3a14e4
+
3a14e4
+	  for (i = 0, internal_reloc = internal_relocs, native_reloc = native_relocs;
3a14e4
+	       i < reloc_count;
3a14e4
+	       i++, internal_reloc++, native_reloc += entsize)
3a14e4
+	    {
3a14e4
+	      ;
3a14e4
+	      Elf_Internal_Rela rela;
3a14e4
+
3a14e4
+	      ebd->s->swap_reloca_in (abfd, native_reloc, & rela);
3a14e4
+
3a14e4
+	      /* The address of an ELF reloc is section relative for an object
3a14e4
+		 file, and absolute for an executable file or shared library.
3a14e4
+		 The address of a normal BFD reloc is always section relative,
3a14e4
+		 and the address of a dynamic reloc is absolute..  */
3a14e4
+	      if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)
3a14e4
+		internal_reloc->address = rela.r_offset;
3a14e4
+	      else
3a14e4
+		internal_reloc->address = rela.r_offset - sec->vma;
3a14e4
+
3a14e4
+	      if (r_sym (rela.r_info) == STN_UNDEF)
3a14e4
+		{
3a14e4
+		  /* FIXME: This and the error case below mean that we
3a14e4
+		     have a symbol on relocs that is not elf_symbol_type.  */
3a14e4
+		  internal_reloc->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
3a14e4
+		}
3a14e4
+	      else if (r_sym (rela.r_info) > symcount)
3a14e4
+		{
3a14e4
+		  _bfd_error_handler
3a14e4
+		    /* xgettext:c-format */
3a14e4
+		    (_("%pB(%pA): relocation %d has invalid symbol index %ld"),
3a14e4
+		     abfd, sec, i, (long) r_sym (rela.r_info));
3a14e4
+		  bfd_set_error (bfd_error_bad_value);
3a14e4
+		  internal_reloc->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
3a14e4
+		  result = FALSE;
3a14e4
+		}
3a14e4
+	      else
3a14e4
+		{
3a14e4
+		  asymbol **ps;
3a14e4
+
3a14e4
+		  ps = symbols + r_sym (rela.r_info) - 1;
3a14e4
+
3a14e4
+		  internal_reloc->sym_ptr_ptr = ps;
3a14e4
+		  /* Make sure that this symbol is not removed by strip.  */
3a14e4
+		  (*ps)->flags |= BSF_KEEP;
3a14e4
+		}
3a14e4
+
3a14e4
+	      internal_reloc->addend = rela.r_addend;
3a14e4
+
3a14e4
+	      ebd->elf_info_to_howto (abfd, internal_reloc, & rela);
3a14e4
+	      if (internal_reloc->howto == NULL)
3a14e4
+		{
3a14e4
+#if DEBUG_SECONDARY_RELOCS
3a14e4
+		  fprintf (stderr, "there is no howto associated with reloc %lx\n", rela.r_info);
3a14e4
+#endif
3a14e4
+		  result = FALSE;
3a14e4
+		}
3a14e4
+	    }
3a14e4
+
3a14e4
+	  free (native_relocs);
3a14e4
+	  /* Store the internal relocs.  */
3a14e4
+	  elf_section_data (relsec)->sec_info = internal_relocs;
3a14e4
+	}
3a14e4
+    }
3a14e4
+
3a14e4
+  return result;
3a14e4
+}
3a14e4
+
3a14e4
+/* Set the ELF section header fields of an output secondary reloc section.  */
3a14e4
+
3a14e4
+bfd_boolean
3a14e4
+_bfd_elf_copy_special_section_fields (const bfd *               ibfd ATTRIBUTE_UNUSED,
3a14e4
+				      bfd *                     obfd ATTRIBUTE_UNUSED,
3a14e4
+				      const Elf_Internal_Shdr * isection,
3a14e4
+				      Elf_Internal_Shdr *       osection)
3a14e4
+{
3a14e4
+  if (isection->sh_type != SHT_SECONDARY_RELOC)
3a14e4
+    return TRUE;
3a14e4
+
3a14e4
+  if (isection == NULL)
3a14e4
+    return FALSE;
3a14e4
+
3a14e4
+  asection * isec = isection->bfd_section;
3a14e4
+  if (isec == NULL)
3a14e4
+    return FALSE;
3a14e4
+
3a14e4
+  asection * osec = osection->bfd_section;
3a14e4
+  if (osec == NULL)
3a14e4
+    return FALSE;
3a14e4
+
3a14e4
+  BFD_ASSERT (elf_section_data (osec)->sec_info == NULL);
3a14e4
+  elf_section_data (osec)->sec_info = elf_section_data (isec)->sec_info;
3a14e4
+  osection->sh_type = SHT_RELA;
3a14e4
+  osection->sh_link = elf_onesymtab (obfd);
3a14e4
+  if (osection->sh_link == 0)
3a14e4
+    {
3a14e4
+      /* There is no symbol table - we are hosed...  */
3a14e4
+      _bfd_error_handler
3a14e4
+	/* xgettext:c-format */
3a14e4
+	(_("%pB(%pA): link section cannot be set because the output file does not have a symbol table"),
3a14e4
+	obfd, osec);
3a14e4
+      bfd_set_error (bfd_error_bad_value);
3a14e4
+      return FALSE;
3a14e4
+    }
3a14e4
+
3a14e4
+  /* Find the output section that corresponds to the isection's sh_info link.  */
3a14e4
+  BFD_ASSERT (isection->sh_info > 0 && isection->sh_info < elf_numsections (ibfd));
3a14e4
+  isection = elf_elfsections (ibfd)[isection->sh_info];
3a14e4
+
3a14e4
+  BFD_ASSERT (isection != NULL);
3a14e4
+  BFD_ASSERT (isection->bfd_section != NULL);
3a14e4
+  BFD_ASSERT (isection->bfd_section->output_section != NULL);
3a14e4
+  osection->sh_info = elf_section_data (isection->bfd_section->output_section)->this_idx;
3a14e4
+
3a14e4
+#if DEBUG_SECONDARY_RELOCS
3a14e4
+  fprintf (stderr, "update header of %s, sh_link = %u, sh_info = %u\n",
3a14e4
+	   osec->name, osection->sh_link, osection->sh_info);
3a14e4
+#endif
3a14e4
+
3a14e4
+  return TRUE;
3a14e4
+}
3a14e4
+
3a14e4
+/* Write out a secondary reloc section.  */
3a14e4
+
3a14e4
+bfd_boolean
3a14e4
+_bfd_elf_write_secondary_reloc_section (bfd *abfd, asection *sec)
3a14e4
+{
3a14e4
+  const struct elf_backend_data * const ebd = get_elf_backend_data (abfd);
3a14e4
+  bfd_vma addr_offset;
3a14e4
+  asection * relsec;
3a14e4
+  bfd_vma (*r_info) (bfd_vma, bfd_vma);
3a14e4
+
3a14e4
+#ifdef BFD64
3a14e4
+  if (bfd_arch_bits_per_address (abfd) != 32)
3a14e4
+    r_info = elf64_r_info;
3a14e4
+  else
3a14e4
+#endif
3a14e4
+    r_info = elf32_r_info;
3a14e4
+
3a14e4
+  if (sec == NULL)
3a14e4
+    return FALSE;
3a14e4
+
3a14e4
+  /* The address of an ELF reloc is section relative for an object
3a14e4
+     file, and absolute for an executable file or shared library.
3a14e4
+     The address of a BFD reloc is always section relative.  */
3a14e4
+  addr_offset = 0;
3a14e4
+  if ((abfd->flags & (EXEC_P | DYNAMIC)) != 0)
3a14e4
+    addr_offset = sec->vma;
3a14e4
+
3a14e4
+  /* Discover if there are any secondary reloc sections
3a14e4
+     associated with SEC.  */
3a14e4
+  for (relsec = abfd->sections; relsec != NULL; relsec = relsec->next)
3a14e4
+    {
3a14e4
+      const struct bfd_elf_section_data * const esd = elf_section_data (relsec);
3a14e4
+      Elf_Internal_Shdr * const hdr = (Elf_Internal_Shdr *) & esd->this_hdr;
3a14e4
+
3a14e4
+      if (hdr->sh_type == SHT_RELA
3a14e4
+	  && hdr->sh_info == (unsigned) elf_section_data (sec)->this_idx)
3a14e4
+	{
3a14e4
+	  asymbol *    last_sym;
3a14e4
+	  int          last_sym_idx;
3a14e4
+	  unsigned int reloc_count;
3a14e4
+	  unsigned int idx;
3a14e4
+	  arelent *    src_irel;
3a14e4
+	  bfd_byte *   dst_rela;
3a14e4
+
3a14e4
+	  BFD_ASSERT (hdr->contents == NULL);
3a14e4
+
3a14e4
+	  reloc_count = hdr->sh_size / hdr->sh_entsize;
3a14e4
+	  BFD_ASSERT (reloc_count > 0);
3a14e4
+
3a14e4
+	  hdr->contents = bfd_alloc (abfd, hdr->sh_size);
3a14e4
+	  if (hdr->contents == NULL)
3a14e4
+	    continue;
3a14e4
+
3a14e4
+#if DEBUG_SECONDARY_RELOCS
3a14e4
+	  fprintf (stderr, "write %u secondary relocs for %s from %s\n", reloc_count, sec->name, relsec->name);
3a14e4
+#endif
3a14e4
+	  last_sym = NULL;
3a14e4
+	  last_sym_idx = 0;
3a14e4
+	  dst_rela = hdr->contents;
3a14e4
+	  src_irel = (arelent *) esd->sec_info;
3a14e4
+	  BFD_ASSERT (src_irel != NULL);
3a14e4
+
3a14e4
+	  for (idx = 0; idx < reloc_count; idx++, dst_rela += hdr->sh_entsize)
3a14e4
+	    {
3a14e4
+	      Elf_Internal_Rela src_rela;
3a14e4
+	      arelent *ptr;
3a14e4
+	      asymbol *sym;
3a14e4
+	      int n;
3a14e4
+
3a14e4
+	      ptr = src_irel + idx;
3a14e4
+	      sym = *ptr->sym_ptr_ptr;
3a14e4
+
3a14e4
+	      if (sym == last_sym)
3a14e4
+		n = last_sym_idx;
3a14e4
+	      else
3a14e4
+		{
3a14e4
+		  last_sym = sym;
3a14e4
+		  n = _bfd_elf_symbol_from_bfd_symbol (abfd, & sym);
3a14e4
+		  if (n < 0)
3a14e4
+		    {
3a14e4
+#if DEBUG_SECONDARY_RELOCS
3a14e4
+		      fprintf (stderr, "failed to find symbol %s whilst rewriting relocs\n",
3a14e4
+			       sym->name);
3a14e4
+#endif
3a14e4
+		      /* FIXME: Signal failure somehow.  */
3a14e4
+		      n = 0;
3a14e4
+		    }
3a14e4
+		  last_sym_idx = n;
3a14e4
+		}
3a14e4
+
3a14e4
+	      if ((*ptr->sym_ptr_ptr)->the_bfd != NULL
3a14e4
+		  && (*ptr->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec
3a14e4
+		  && ! _bfd_elf_validate_reloc (abfd, ptr))
3a14e4
+		{
3a14e4
+#if DEBUG_SECONDARY_RELOCS
3a14e4
+		  fprintf (stderr, "symbol %s is not in the output bfd\n",
3a14e4
+			   sym->name);
3a14e4
+#endif
3a14e4
+		  /* FIXME: Signal failure somehow.  */
3a14e4
+		  n = 0;
3a14e4
+		}
3a14e4
+
3a14e4
+	      if (ptr->howto == NULL)
3a14e4
+		{
3a14e4
+#if DEBUG_SECONDARY_RELOCS
3a14e4
+		  fprintf (stderr, "reloc for symbol %s does not have a howto associated with it\n",
3a14e4
+			   sym->name);
3a14e4
+#endif
3a14e4
+		  /* FIXME: Signal failure somehow.  */
3a14e4
+		  n = 0;
3a14e4
+		}
3a14e4
+
3a14e4
+	      src_rela.r_offset = ptr->address + addr_offset;
3a14e4
+	      src_rela.r_info = r_info (n, ptr->howto->type);
3a14e4
+	      src_rela.r_addend = ptr->addend;
3a14e4
+	      ebd->s->swap_reloca_out (abfd, &src_rela, dst_rela);
3a14e4
+	    }
3a14e4
+	}
3a14e4
+    }
3a14e4
+
3a14e4
+  return TRUE;
3a14e4
+}
3a14e4
+
3a14e4
+/* Preserve any OS or PROCESSOR specific section indicies.  */
3a14e4
+
3a14e4
+unsigned int
3a14e4
+_bfd_elf_symbol_section_index (bfd * abfd ATTRIBUTE_UNUSED,
3a14e4
+			       elf_symbol_type * sym)
3a14e4
+{
3a14e4
+  unsigned int shndx = sym->internal_elf_sym.st_shndx;
3a14e4
+
3a14e4
+  /* Preserve special section indicies.  */
3a14e4
+  return shndx >= SHN_LORESERVE ? shndx : SHN_ABS;
3a14e4
+}
3a14e4
diff -rup binutils.orig/bfd/elfcode.h binutils-2.27/bfd/elfcode.h
3a14e4
--- binutils.orig/bfd/elfcode.h	2020-02-12 14:41:48.902875819 +0000
3a14e4
+++ binutils-2.27/bfd/elfcode.h	2020-02-12 14:41:58.779803037 +0000
3a14e4
@@ -853,6 +853,7 @@ elf_object_p (bfd *abfd)
3a14e4
 void
3a14e4
 elf_write_relocs (bfd *abfd, asection *sec, void *data)
3a14e4
 {
3a14e4
+  const struct elf_backend_data * const bed = get_elf_backend_data (abfd);
3a14e4
   bfd_boolean *failedp = (bfd_boolean *) data;
3a14e4
   Elf_Internal_Shdr *rela_hdr;
3a14e4
   bfd_vma addr_offset;
3a14e4
@@ -961,6 +962,13 @@ elf_write_relocs (bfd *abfd, asection *s
3a14e4
       src_rela.r_addend = ptr->addend;
3a14e4
       (*swap_out) (abfd, &src_rela, dst_rela);
3a14e4
     }
3a14e4
+
3a14e4
+  if (bed->write_secondary_relocs != NULL)
3a14e4
+    if (! bed->write_secondary_relocs (abfd, sec))
3a14e4
+      {
3a14e4
+	*failedp = TRUE;
3a14e4
+	return;
3a14e4
+      }
3a14e4
 }
3a14e4
 
3a14e4
 /* Write out the program headers.  */
3a14e4
@@ -1261,7 +1269,10 @@ elf_slurp_symbol_table (bfd *abfd, asymb
3a14e4
 		{
3a14e4
 		  /* This symbol is in a section for which we did not
3a14e4
 		     create a BFD section.  Just use bfd_abs_section,
3a14e4
-		     although it is wrong.  FIXME.  */
3a14e4
+		     although it is wrong.  FIXME.  Note - there is
3a14e4
+		     code in elf.c:swap_out_syms that calls
3a14e4
+		     symbol_section_index() in the elf backend for
3a14e4
+		     cases like this.  */
3a14e4
 		  sym->symbol.section = bfd_abs_section_ptr;
3a14e4
 		}
3a14e4
 	    }
3a14e4
@@ -1488,6 +1499,7 @@ elf_slurp_reloc_table (bfd *abfd,
3a14e4
 		       asymbol **symbols,
3a14e4
 		       bfd_boolean dynamic)
3a14e4
 {
3a14e4
+  const struct elf_backend_data * const bed = get_elf_backend_data (abfd);
3a14e4
   struct bfd_elf_section_data * const d = elf_section_data (asect);
3a14e4
   Elf_Internal_Shdr *rel_hdr;
3a14e4
   Elf_Internal_Shdr *rel_hdr2;
3a14e4
@@ -1551,6 +1563,10 @@ elf_slurp_reloc_table (bfd *abfd,
3a14e4
 					      symbols, dynamic))
3a14e4
     return FALSE;
3a14e4
 
3a14e4
+  if (bed->slurp_secondary_relocs != NULL
3a14e4
+      && ! bed->slurp_secondary_relocs (abfd, asect, symbols))
3a14e4
+    return FALSE;
3a14e4
+
3a14e4
   asect->relocation = relents;
3a14e4
   return TRUE;
3a14e4
 }
3a14e4
diff -rup binutils.orig/bfd/elflink.c binutils-2.27/bfd/elflink.c
3a14e4
--- binutils.orig/bfd/elflink.c	2020-02-12 14:41:48.896875864 +0000
3a14e4
+++ binutils-2.27/bfd/elflink.c	2020-02-12 14:42:44.663464933 +0000
3a14e4
@@ -11064,6 +11064,10 @@ elf_final_link_free (bfd *obfd, struct e
3a14e4
     }
3a14e4
 }
3a14e4
 
3a14e4
+#define is_reloc_section(ESDO)			\
3a14e4
+  (   (ESDO)->this_hdr.sh_type == SHT_REL	\
3a14e4
+   || (ESDO)->this_hdr.sh_type == SHT_RELA)
3a14e4
+
3a14e4
 /* Do the final step of an ELF link.  */
3a14e4
 
3a14e4
 bfd_boolean
3a14e4
@@ -11210,8 +11214,7 @@ bfd_elf_final_link (bfd *abfd, struct bf
3a14e4
 	      if (sec->flags & SEC_MERGE)
3a14e4
 		merged = TRUE;
3a14e4
 
3a14e4
-	      if (esdo->this_hdr.sh_type == SHT_REL
3a14e4
-		  || esdo->this_hdr.sh_type == SHT_RELA)
3a14e4
+	      if (is_reloc_section (esdo))
3a14e4
 		/* Some backends use reloc_count in relocation sections
3a14e4
 		   to count particular types of relocs.  Of course,
3a14e4
 		   reloc sections themselves can't have relocations.  */
3a14e4
diff -rup binutils.orig/bfd/elfxx-target.h binutils-2.27/bfd/elfxx-target.h
3a14e4
--- binutils.orig/bfd/elfxx-target.h	2020-02-12 14:41:48.903875812 +0000
3a14e4
+++ binutils-2.27/bfd/elfxx-target.h	2020-02-12 14:41:58.780803030 +0000
3a14e4
@@ -690,7 +690,7 @@
3a14e4
 #endif
3a14e4
 
3a14e4
 #ifndef elf_backend_copy_special_section_fields
3a14e4
-#define elf_backend_copy_special_section_fields NULL
3a14e4
+#define elf_backend_copy_special_section_fields _bfd_elf_copy_special_section_fields
3a14e4
 #endif
3a14e4
 
3a14e4
 #ifndef elf_backend_compact_eh_encoding
3a14e4
@@ -698,7 +698,23 @@
3a14e4
 #endif
3a14e4
 
3a14e4
 #ifndef elf_backend_cant_unwind_opcode
3a14e4
-#define elf_backend_cant_unwind_opcode 0
3a14e4
+#define elf_backend_cant_unwind_opcode NULL
3a14e4
+#endif
3a14e4
+
3a14e4
+#ifndef elf_backend_init_secondary_reloc_section
3a14e4
+#define elf_backend_init_secondary_reloc_section _bfd_elf_init_secondary_reloc_section
3a14e4
+#endif
3a14e4
+
3a14e4
+#ifndef elf_backend_slurp_secondary_reloc_section
3a14e4
+#define elf_backend_slurp_secondary_reloc_section _bfd_elf_slurp_secondary_reloc_section
3a14e4
+#endif
3a14e4
+
3a14e4
+#ifndef elf_backend_write_secondary_reloc_section
3a14e4
+#define elf_backend_write_secondary_reloc_section _bfd_elf_write_secondary_reloc_section
3a14e4
+#endif
3a14e4
+
3a14e4
+#ifndef elf_backend_symbol_section_index
3a14e4
+#define elf_backend_symbol_section_index _bfd_elf_symbol_section_index
3a14e4
 #endif
3a14e4
 
3a14e4
 #ifndef elf_match_priority
3a14e4
@@ -817,6 +833,10 @@ static struct elf_backend_data elfNN_bed
3a14e4
   elf_backend_obj_attrs_handle_unknown,
3a14e4
   elf_backend_compact_eh_encoding,
3a14e4
   elf_backend_cant_unwind_opcode,
3a14e4
+  elf_backend_init_secondary_reloc_section,
3a14e4
+  elf_backend_slurp_secondary_reloc_section,
3a14e4
+  elf_backend_write_secondary_reloc_section,
3a14e4
+  elf_backend_symbol_section_index,
3a14e4
   elf_backend_static_tls_alignment,
3a14e4
   elf_backend_stack_align,
3a14e4
   elf_backend_strtab_flags,
3a14e4