4341cae
commit b065d4a401e2120c11c92357b213a85e6d70f300
4341cae
Author: Mark Wielaard <mark@klomp.org>
4341cae
Date:   Wed Jun 7 20:32:38 2017 +0200
4341cae
4341cae
    strip: Don't generate empty output file when nothing to do.
4341cae
    
4341cae
    If there was nothing to do strip would skip generating a separate
4341cae
    debug file if one was requested, but it would also not finish the
4341cae
    creation of a new output file (with the non-stripped sections).
4341cae
    Also if there was an error any partially created output would be kept.
4341cae
    
4341cae
    Make sure that when the -o output file option is given we always generate
4341cae
    a complete output file (except on error). Also make sure that when the -f
4341cae
    debug file option is given it is only generated when it is not empty.
4341cae
    
4341cae
    Add testcase run-strip-nothing.sh that tests the various combinations.
4341cae
    
4341cae
    https://sourceware.org/bugzilla/show_bug.cgi?id=21522
4341cae
    
4341cae
    Signed-off-by: Mark Wielaard <mark@klomp.org>
4341cae
4341cae
diff --git a/src/ChangeLog b/src/ChangeLog
4341cae
index 6ac0ef2..e19122e 100644
4341cae
--- a/src/ChangeLog
4341cae
+++ b/src/ChangeLog
4341cae
@@ -1,3 +1,9 @@
4341cae
+2017-06-07  Mark Wielaard  <mark@klomp.org>
4341cae
+
4341cae
+	* strip.c (handle_elf): Introduce new handle_elf boolean. Use it to
4341cae
+	determine whether to create an output and/or debug file. Remove new
4341cae
+	output file on error.
4341cae
+
4341cae
 2017-06-06  Mark Wielaard  <mark@klomp.org>
4341cae
 
4341cae
 	* strip.c (handle_elf): Assume e_shstrndx section can be removed.
4341cae
diff --git a/src/strip.c b/src/strip.c
4341cae
index 11b2a37..2bf95f9 100644
4341cae
--- a/src/strip.c
4341cae
+++ b/src/strip.c
4341cae
@@ -1063,15 +1063,17 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
4341cae
 	shdr_info[cnt].se = dwelf_strtab_add (shst, shdr_info[cnt].name);
4341cae
       }
4341cae
 
4341cae
-  /* Test whether we are doing anything at all.  */
4341cae
-  if (cnt == idx
4341cae
-      || (cnt == idx + 1 && shdr_info[ehdr->e_shstrndx].idx == 0))
4341cae
-    /* Nope, all removable sections are already gone.  Or the only section
4341cae
-       we would remove is the .shstrtab section which we will add again.  */
4341cae
-    goto fail_close;
4341cae
-
4341cae
-  /* Create the reference to the file with the debug info.  */
4341cae
-  if (debug_fname != NULL && !remove_shdrs)
4341cae
+  /* Test whether we are doing anything at all.  Either all removable
4341cae
+     sections are already gone.  Or the only section we would remove is
4341cae
+     the .shstrtab section which we would add again.  */
4341cae
+  bool removing_sections = !(cnt == idx
4341cae
+			     || (cnt == idx + 1
4341cae
+				 && shdr_info[ehdr->e_shstrndx].idx == 0));
4341cae
+  if (output_fname == NULL && !removing_sections)
4341cae
+      goto fail_close;
4341cae
+
4341cae
+  /* Create the reference to the file with the debug info (if any).  */
4341cae
+  if (debug_fname != NULL && !remove_shdrs && removing_sections)
4341cae
     {
4341cae
       /* Add the section header string table section name.  */
4341cae
       shdr_info[cnt].se = dwelf_strtab_add_len (shst, ".gnu_debuglink", 15);
4341cae
@@ -1759,7 +1761,8 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
4341cae
   /* Remove any relocations between debug sections in ET_REL
4341cae
      for the debug file when requested.  These relocations are always
4341cae
      zero based between the unallocated sections.  */
4341cae
-  if (debug_fname != NULL && reloc_debug && ehdr->e_type == ET_REL)
4341cae
+  if (debug_fname != NULL && removing_sections
4341cae
+      && reloc_debug && ehdr->e_type == ET_REL)
4341cae
     {
4341cae
       scn = NULL;
4341cae
       cnt = 0;
4341cae
@@ -1997,7 +2000,7 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
4341cae
 
4341cae
   /* Now that we have done all adjustments to the data,
4341cae
      we can actually write out the debug file.  */
4341cae
-  if (debug_fname != NULL)
4341cae
+  if (debug_fname != NULL && removing_sections)
4341cae
     {
4341cae
       /* Finally write the file.  */
4341cae
       if (unlikely (elf_update (debugelf, ELF_C_WRITE) == -1))
4341cae
@@ -2230,7 +2233,11 @@ cannot set access and modification date of '%s'"),
4341cae
 
4341cae
   /* Close the file descriptor if we created a new file.  */
4341cae
   if (output_fname != NULL)
4341cae
-    close (fd);
4341cae
+    {
4341cae
+      close (fd);
4341cae
+      if (result != 0)
4341cae
+       unlink (output_fname);
4341cae
+    }
4341cae
 
4341cae
   return result;
4341cae
 }
4341cae
diff --git a/tests/ChangeLog b/tests/ChangeLog
4341cae
index 5800946..5550eac 100644
4341cae
--- a/tests/ChangeLog
4341cae
+++ b/tests/ChangeLog
4341cae
@@ -1,3 +1,9 @@
4341cae
+2017-06-07  Mark Wielaard  <mark@klomp.org>
4341cae
+
4341cae
+	* run-strip-nothing.sh: New test.
4341cae
+	* Makefile.am (TESTS): Add run-strip-nothing.sh.
4341cae
+	(EXTRA_DIST): Likewise.
4341cae
+
4341cae
 2017-06-06  Mark Wielaard  <mark@klomp.org>
4341cae
 
4341cae
 	* run-strip-test.sh: Test strip -g doesn't introduce extra .shstrtab.
4341cae
diff --git a/tests/Makefile.am b/tests/Makefile.am
4341cae
index 3a12fe3..28e997c 100644
4341cae
--- a/tests/Makefile.am
4341cae
+++ b/tests/Makefile.am
4341cae
@@ -81,6 +81,7 @@ TESTS = run-arextract.sh run-arsymtest.sh newfile test-nlist \
4341cae
 	run-strip-test3.sh run-strip-test4.sh run-strip-test5.sh \
4341cae
 	run-strip-test6.sh run-strip-test7.sh run-strip-test8.sh \
4341cae
 	run-strip-test9.sh run-strip-test10.sh run-strip-test11.sh \
4341cae
+	run-strip-nothing.sh \
4341cae
 	run-strip-groups.sh run-strip-reloc.sh run-strip-strmerge.sh \
4341cae
 	run-strip-nobitsalign.sh \
4341cae
 	run-unstrip-test.sh run-unstrip-test2.sh run-unstrip-test3.sh \
4341cae
@@ -174,6 +175,7 @@ EXTRA_DIST = run-arextract.sh run-arsymtest.sh \
4341cae
 	     run-strip-test4.sh run-strip-test5.sh run-strip-test6.sh \
4341cae
 	     run-strip-test7.sh run-strip-test8.sh run-strip-groups.sh \
4341cae
 	     run-strip-test9.sh run-strip-test10.sh run-strip-test11.sh \
4341cae
+	     run-strip-nothing.sh \
4341cae
 	     run-strip-strmerge.sh run-strip-nobitsalign.sh \
4341cae
 	     testfile-nobitsalign.bz2 testfile-nobitsalign.strip.bz2 \
4341cae
 	     run-strip-reloc.sh hello_i386.ko.bz2 hello_x86_64.ko.bz2 \
4341cae
diff --git a/tests/run-strip-nothing.sh b/tests/run-strip-nothing.sh
4341cae
new file mode 100755
4341cae
index 0000000..e80bd90
4341cae
--- /dev/null
4341cae
+++ b/tests/run-strip-nothing.sh
4341cae
@@ -0,0 +1,62 @@
4341cae
+#! /bin/sh
4341cae
+# Copyright (C) 2017 Red Hat, Inc.
4341cae
+# This file is part of elfutils.
4341cae
+#
4341cae
+# This file is free software; you can redistribute it and/or modify
4341cae
+# it under the terms of the GNU General Public License as published by
4341cae
+# the Free Software Foundation; either version 3 of the License, or
4341cae
+# (at your option) any later version.
4341cae
+#
4341cae
+# elfutils is distributed in the hope that it will be useful, but
4341cae
+# WITHOUT ANY WARRANTY; without even the implied warranty of
4341cae
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
4341cae
+# GNU General Public License for more details.
4341cae
+#
4341cae
+# You should have received a copy of the GNU General Public License
4341cae
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
4341cae
+
4341cae
+. $srcdir/test-subr.sh
4341cae
+
4341cae
+# If there is nothing to strip then -o output should be identical to input.
4341cae
+# And there should not be an (empty) -f debug file.
4341cae
+
4341cae
+tempfiles a.out strip.out debug.out
4341cae
+
4341cae
+# Create no-debug a.out.
4341cae
+echo "int main() { return 1; }" | gcc -xc -
4341cae
+
4341cae
+# strip to file
4341cae
+testrun ${abs_top_builddir}/src/strip -g -o strip.out ||
4341cae
+  { echo "*** failed to strip -g -o strip.out a.out"; exit -1; }
4341cae
+
4341cae
+testrun ${abs_top_builddir}/src/elfcmp a.out strip.out ||
4341cae
+  { echo "*** failed strip.out different from a.out"; exit -1; }
4341cae
+
4341cae
+# strip original
4341cae
+testrun ${abs_top_builddir}/src/strip -g ||
4341cae
+  { echo "*** failed to strip -g a.out"; exit -1; }
4341cae
+
4341cae
+testrun ${abs_top_builddir}/src/elfcmp strip.out a.out ||
4341cae
+  { echo "*** failed a.out different from strip.out"; exit -1; }
4341cae
+
4341cae
+# strip to file with debug file
4341cae
+testrun ${abs_top_builddir}/src/strip -g -o strip.out -f debug.out ||
4341cae
+  { echo "*** failed to strip -g -o strip.out -f debug.out a.out"; exit -1; }
4341cae
+
4341cae
+testrun ${abs_top_builddir}/src/elfcmp a.out strip.out ||
4341cae
+  { echo "*** failed strip.out different from a.out (with debug)"; exit -1; }
4341cae
+
4341cae
+test ! -f debug.out ||
4341cae
+  { echo "*** failed strip.out and debug.out exist"; exit -1; }
4341cae
+
4341cae
+# strip original with debug file
4341cae
+testrun ${abs_top_builddir}/src/strip -g -f debug.out ||
4341cae
+  { echo "*** failed to strip -g -f debug.out a.out"; exit -1; }
4341cae
+
4341cae
+testrun ${abs_top_builddir}/src/elfcmp strip.out a.out ||
4341cae
+  { echo "*** failed a.out different from strip.out (with debug)"; exit -1; }
4341cae
+
4341cae
+test ! -f debug.out ||
4341cae
+  { echo "*** failed a.out and debug.out exist"; exit -1; }
4341cae
+
4341cae
+exit 0
4341cae
--- elfutils-0.169/tests/Makefile.in.orig	2017-06-07 21:48:55.475994222 +0200
4341cae
+++ elfutils-0.169/tests/Makefile.in	2017-06-07 21:49:20.441430261 +0200
4341cae
@@ -138,8 +138,8 @@
4341cae
 	run-strip-test.sh run-strip-test2.sh run-strip-test3.sh \
4341cae
 	run-strip-test4.sh run-strip-test5.sh run-strip-test6.sh \
4341cae
 	run-strip-test7.sh run-strip-test8.sh run-strip-test9.sh \
4341cae
-	run-strip-test10.sh run-strip-test11.sh run-strip-groups.sh \
4341cae
-	run-strip-reloc.sh run-strip-strmerge.sh \
4341cae
+	run-strip-test10.sh run-strip-test11.sh run-strip-nothing.sh \
4341cae
+	run-strip-groups.sh run-strip-reloc.sh run-strip-strmerge.sh \
4341cae
 	run-strip-nobitsalign.sh run-unstrip-test.sh \
4341cae
 	run-unstrip-test2.sh run-unstrip-test3.sh run-unstrip-test4.sh \
4341cae
 	run-unstrip-M.sh run-elfstrmerge-test.sh run-ecp-test.sh \
4341cae
@@ -1046,6 +1046,7 @@
4341cae
 	     run-strip-test4.sh run-strip-test5.sh run-strip-test6.sh \
4341cae
 	     run-strip-test7.sh run-strip-test8.sh run-strip-groups.sh \
4341cae
 	     run-strip-test9.sh run-strip-test10.sh run-strip-test11.sh \
4341cae
+	     run-strip-nothing.sh \
4341cae
 	     run-strip-strmerge.sh run-strip-nobitsalign.sh \
4341cae
 	     testfile-nobitsalign.bz2 testfile-nobitsalign.strip.bz2 \
4341cae
 	     run-strip-reloc.sh hello_i386.ko.bz2 hello_x86_64.ko.bz2 \
4341cae
@@ -2332,6 +2333,13 @@
4341cae
 	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
4341cae
 	--log-file $$b.log --trs-file $$b.trs \
4341cae
 	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
4341cae
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
4341cae
+run-strip-nothing.sh.log: run-strip-nothing.sh
4341cae
+	@p='run-strip-nothing.sh'; \
4341cae
+	b='run-strip-nothing.sh'; \
4341cae
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
4341cae
+	--log-file $$b.log --trs-file $$b.trs \
4341cae
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
4341cae
 	"$$tst" $(AM_TESTS_FD_REDIRECT)
4341cae
 run-strip-groups.sh.log: run-strip-groups.sh
4341cae
 	@p='run-strip-groups.sh'; \