diff options
author | Nick Clifton <nickc@redhat.com> | 2017-12-08 10:07:14 +0000 |
---|---|---|
committer | Nick Clifton <nickc@redhat.com> | 2017-12-08 10:07:14 +0000 |
commit | 2d054e6bfdfb0f58fb9cc501c29327df34fec697 (patch) | |
tree | 9ac200639d7ff30b0da20b6ad2d431a5bbb35b1e /binutils/objcopy.c | |
parent | c8bed57010e8789212a6841db4b397b175a00f9e (diff) | |
download | gdb-2d054e6bfdfb0f58fb9cc501c29327df34fec697.zip gdb-2d054e6bfdfb0f58fb9cc501c29327df34fec697.tar.gz gdb-2d054e6bfdfb0f58fb9cc501c29327df34fec697.tar.bz2 |
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.
Diffstat (limited to 'binutils/objcopy.c')
-rw-r--r-- | binutils/objcopy.c | 27 |
1 files changed, 19 insertions, 8 deletions
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; } |