[binutils-gdb] Fix stripping relocs in a file with mergeable notes.

Nick Clifton nickc@sourceware.org
Fri Dec 8 10:08:00 GMT 2017


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=2d054e6bfdfb0f58fb9cc501c29327df34fec697

commit 2d054e6bfdfb0f58fb9cc501c29327df34fec697
Author: Nick Clifton <nickc@redhat.com>
Date:   Fri Dec 8 10:07:14 2017 +0000

    Fix stripping relocs in a file with mergeable notes.
    
      A recent Fedora bug (1520805) exposed a problem with objcopy's reloc
      copying code, when a binary also contains mergeable notes.  The note
      merging code would delete some relocs, but then the reloc copying code
      would try to put them back again, which did not work.
    
      So I am checking in the patch below to fix the problem.  The patch
      also tweaks one of the binutils note merging tests so that it is
      skipped for the Sparc64 target, since this has funky relocs.
    
    binutils	* objcopy.c (copy_relocations_in_section): Use the orelocations
    	field of the input section, if it has been initialised.
    	* testsuite/binutils-all/note-2-64.d: Skip test on Sparc64.
    
    bfd	* elfcode.h (elf_write_relocs): Check for an empty howto field.

Diff:
---
 bfd/ChangeLog                               |  4 ++++
 bfd/elfcode.h                               |  6 ++++++
 binutils/ChangeLog                          |  6 ++++++
 binutils/objcopy.c                          | 27 +++++++++++++++++++--------
 binutils/testsuite/binutils-all/note-2-64.d |  4 ++++
 5 files changed, 39 insertions(+), 8 deletions(-)

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 455153c..7f59fa0 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,7 @@
+2017-12-08  Nick Clifton  <nickc@redhat.com>
+
+	* elfcode.h (elf_write_relocs): Check for an empty howto field.
+
 2017-12-08  Sangamesh Mallayya  <sangamesh.swamy@in.ibm.com>
 
 	* bfd.c (bfd_get_sign_extend_vma): Handle aix5coff64-rs6000.
diff --git a/bfd/elfcode.h b/bfd/elfcode.h
index 80b26aa..00684d5 100644
--- a/bfd/elfcode.h
+++ b/bfd/elfcode.h
@@ -958,6 +958,12 @@ elf_write_relocs (bfd *abfd, asection *sec, void *data)
 	  return;
 	}
 
+      if (ptr->howto == NULL)
+	{
+	  *failedp = TRUE;
+	  return;
+	}
+
       src_rela.r_offset = ptr->address + addr_offset;
       src_rela.r_info = ELF_R_INFO (n, ptr->howto->type);
       src_rela.r_addend = ptr->addend;
diff --git a/binutils/ChangeLog b/binutils/ChangeLog
index 058ebf3..4f29d19 100644
--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -1,3 +1,9 @@
+2017-12-08  Nick Clifton  <nickc@redhat.com>
+
+	* objcopy.c (copy_relocations_in_section): Use the orelocations
+	field of the input section, if it has been initialised.
+	* testsuite/binutils-all/note-2-64.d: Skip test on Sparc64.
+
 2017-12-06  Jim Wilson  <jimw@sifive.com>
 
 	PR 22465
diff --git a/binutils/objcopy.c b/binutils/objcopy.c
index f40b355..5026fd8 100644
--- a/binutils/objcopy.c
+++ b/binutils/objcopy.c
@@ -3785,14 +3785,24 @@ copy_relocations_in_section (bfd *ibfd, sec_ptr isection, void *obfdarg)
     }
   else
     {
-      relpp = (arelent **) xmalloc (relsize);
-      relcount = bfd_canonicalize_reloc (ibfd, isection, relpp, isympp);
-      if (relcount < 0)
+      if (isection->orelocation != NULL)
 	{
-	  status = 1;
-	  bfd_nonfatal_message (NULL, ibfd, isection,
-				_("relocation count is negative"));
-	  return;
+	  /* Some other function has already set up the output relocs
+	     for us, so scan those instead of the default relocs.  */
+	  relcount = isection->reloc_count;
+	  relpp = isection->orelocation;
+	}
+      else
+	{
+	  relpp = (arelent **) xmalloc (relsize);
+	  relcount = bfd_canonicalize_reloc (ibfd, isection, relpp, isympp);
+	  if (relcount < 0)
+	    {
+	      status = 1;
+	      bfd_nonfatal_message (NULL, ibfd, isection,
+				    _("relocation count is negative"));
+	      return;
+	    }
 	}
 
       if (strip_symbols == STRIP_ALL)
@@ -3815,7 +3825,8 @@ copy_relocations_in_section (bfd *ibfd, sec_ptr isection, void *obfdarg)
 		  temp_relpp [temp_relcount++] = relpp [i];
 	    }
 	  relcount = temp_relcount;
-	  free (relpp);
+	  if (isection->orelocation == NULL)
+	    free (relpp);
 	  relpp = temp_relpp;
 	}
 
diff --git a/binutils/testsuite/binutils-all/note-2-64.d b/binutils/testsuite/binutils-all/note-2-64.d
index 8535821..f9be897 100644
--- a/binutils/testsuite/binutils-all/note-2-64.d
+++ b/binutils/testsuite/binutils-all/note-2-64.d
@@ -3,6 +3,10 @@
 #objcopy: --merge-notes
 #name: merge notes section (64-bits)
 #source: note-2-64.s
+#not-target: sparc64-*-*
+# Internally the Sparc64 backend uses two relocs for every one reloc visible externally.
+# Unfortunately the BFD library does not provide a target specific way to delete individual
+# relocs, so the note merging feature fails.
 
 #...
   Owner                 Data size	Description



More information about the Binutils-cvs mailing list