This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Commit: Fix reloc stripping on binaries with mergeable notes
- From: Nick Clifton <nickc at redhat dot com>
- To: binutils at sourceware dot org
- Date: Fri, 08 Dec 2017 10:07:02 +0000
- Subject: Commit: Fix reloc stripping on binaries with mergeable notes
- Authentication-results: sourceware.org; auth=none
Hi Guys,
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.
Cheers
Nick
binutils/ChangeLog
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.
bfd/ChangeLog
2017-12-08 Nick Clifton <nickc@redhat.com>
* elfcode.h (elf_write_relocs): Check for an empty howto field.
diff --git a/bfd/elfcode.h b/bfd/elfcode.h
index 80b26aa803..00684d5960 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/objcopy.c b/binutils/objcopy.c
index f40b355c14..5026fd8af2 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 85358213a2..f9be89756a 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