[binutils-gdb] Fix debug section compression so that it is only performed if it would make the section smaller.

Nick Clifton nickc@sourceware.org
Wed Mar 18 15:48:00 GMT 2015


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

commit 273a49858fa9c8d73de87167618ef99d70f9731a
Author: Jon Turney <jon.turney@dronecode.org.uk>
Date:   Wed Mar 18 15:47:13 2015 +0000

    Fix debug section compression so that it is only performed if it would make the section smaller.
    
    	PR binutils/18087
    gas	* doc/as.texinfo: Note that when gas compresses debug sections the
    	compression is only performed if it makes the section smaller.
    	* write.c (compress_debug): Do not compress a debug section if
    	doing so would make it larger.
    
    tests	* gas/i386/dw2-compress-1.d: Do not expect the .debug_abbrev or
    	.debug_info sections to be compressed.
    
    binu	* doc/binutils.texi: Note that when objcopy compresses debug
    	sections the compression is only performed if it makes the section
    	smaller.
    
    bfd	* coffgen.c (make_a_section_from_file): Only prepend a z to a
    	debug section's name if the section was actually compressed.
    	* elf.c (_bfd_elf_make_section_from_shdr): Likewise.
    	* compress.c (bfd_init_section_compress_status): Do not compress
    	the section if doing so would make it bigger.  In such cases leave
    	the section alone and return COMPRESS_SECTION_NONE.

Diff:
---
 bfd/ChangeLog                           | 11 +++++++++++
 bfd/coffgen.c                           | 21 ++++++++++++---------
 bfd/compress.c                          | 13 ++++++++++++-
 bfd/elf.c                               | 24 +++++++++++++++---------
 binutils/ChangeLog                      |  8 ++++++++
 binutils/doc/binutils.texi              |  8 ++++++--
 gas/ChangeLog                           |  9 +++++++++
 gas/doc/as.texinfo                      |  3 ++-
 gas/testsuite/ChangeLog                 |  7 +++++++
 gas/testsuite/gas/i386/dw2-compress-1.d |  4 ++--
 gas/write.c                             |  5 +++++
 11 files changed, 89 insertions(+), 24 deletions(-)

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 9173e17..c5f109e 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,14 @@
+2015-03-18  Jon Turney  <jon.turney@dronecode.org.uk>
+	    Nick Clifton  <nickc@redhat.com>
+
+	PR binutils/18087
+	* coffgen.c (make_a_section_from_file): Only prepend a z to a
+	debug section's name if the section was actually compressed.
+	* elf.c (_bfd_elf_make_section_from_shdr): Likewise.
+	* compress.c (bfd_init_section_compress_status): Do not compress
+	the section if doing so would make it bigger.  In such cases leave
+	the section alone and return COMPRESS_SECTION_NONE.
+
 2015-03-17  Alan Modra  <amodra@gmail.com>
 
 	* elf64-ppc.c (ppc64_elf_get_synthetic_symtab): Return count of 0
diff --git a/bfd/coffgen.c b/bfd/coffgen.c
index 5c664a4..b1ab56e 100644
--- a/bfd/coffgen.c
+++ b/bfd/coffgen.c
@@ -178,18 +178,21 @@ make_a_section_from_file (bfd *abfd,
 		 abfd, name);
 	      return FALSE;
 	    }
-	  if (name[1] != 'z')
+	  if (return_section->compress_status == COMPRESS_SECTION_DONE)
 	    {
-	      unsigned int len = strlen (name);
+	      if (name[1] != 'z')
+		{
+		  unsigned int len = strlen (name);
 
-	      new_name = bfd_alloc (abfd, len + 2);
-	      if (new_name == NULL)
-		return FALSE;
-	      new_name[0] = '.';
-	      new_name[1] = 'z';
-	      memcpy (new_name + 2, name + 1, len);
+		  new_name = bfd_alloc (abfd, len + 2);
+		  if (new_name == NULL)
+		    return FALSE;
+		  new_name[0] = '.';
+		  new_name[1] = 'z';
+		  memcpy (new_name + 2, name + 1, len);
+		}
 	    }
-	  break;
+         break;
 	case decompress:
 	  if (!bfd_init_section_decompress_status (abfd, return_section))
 	    {
diff --git a/bfd/compress.c b/bfd/compress.c
index 0087a66..ad1fbee 100644
--- a/bfd/compress.c
+++ b/bfd/compress.c
@@ -441,7 +441,18 @@ bfd_init_section_compress_status (bfd *abfd ATTRIBUTE_UNUSED,
 					 uncompressed_buffer,
 					 uncompressed_size);
 
-  free (uncompressed_buffer);
+  /* PR binutils/18087: If compression didn't make
+     the section smaller, just keep it uncompressed.  */
+  if (ret && uncompressed_size < sec->size)
+    {
+      free (sec->contents);
+      sec->contents = uncompressed_buffer;
+      sec->size = uncompressed_size;
+      sec->compress_status = COMPRESS_SECTION_NONE;
+    }
+  else
+    free (uncompressed_buffer);
+
   return ret;
 #endif
 }
diff --git a/bfd/elf.c b/bfd/elf.c
index 13d4272..c4defda 100644
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -1069,16 +1069,22 @@ _bfd_elf_make_section_from_shdr (bfd *abfd,
 		 abfd, name);
 	      return FALSE;
 	    }
-	  if (name[1] != 'z')
+	  /* PR binutils/18087: Compression does not always make a section
+	     smaller.  So only rename the section when compression has
+	     actually taken place.  */
+	  if (newsect->compress_status == COMPRESS_SECTION_DONE)
 	    {
-	      unsigned int len = strlen (name);
-
-	      new_name = bfd_alloc (abfd, len + 2);
-	      if (new_name == NULL)
-		return FALSE;
-	      new_name[0] = '.';
-	      new_name[1] = 'z';
-	      memcpy (new_name + 2, name + 1, len);
+	      if (name[1] != 'z')
+		{
+		  unsigned int len = strlen (name);
+
+		  new_name = bfd_alloc (abfd, len + 2);
+		  if (new_name == NULL)
+		    return FALSE;
+		  new_name[0] = '.';
+		  new_name[1] = 'z';
+		  memcpy (new_name + 2, name + 1, len);
+		}
 	    }
 	  break;
 	case decompress:
diff --git a/binutils/ChangeLog b/binutils/ChangeLog
index f59c0d1..5c0efb1 100644
--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -1,3 +1,11 @@
+2015-03-18  Jon Turney  <jon.turney@dronecode.org.uk>
+	    Nick Clifton  <nickc@redhat.com>
+
+	PR binutils/18087
+	* doc/binutils.texi: Note that when objcopy compresses debug
+	sections the compression is only performed if it makes the section
+	smaller.
+
 2015-03-10  H.J. Lu  <hongjiu.lu@intel.com>
 
 	PR binutils/18101
diff --git a/binutils/doc/binutils.texi b/binutils/doc/binutils.texi
index 22d54be..da50163 100644
--- a/binutils/doc/binutils.texi
+++ b/binutils/doc/binutils.texi
@@ -1844,10 +1844,14 @@ It can also be a useful way of reducing the size of a @option{--just-symbols}
 linker input file.
 
 @item --compress-debug-sections
-Compress DWARF debug sections using zlib.
+Compress DWARF debug sections using zlib.  The debug sections are
+renamed to begin with @samp{.zdebug} instead of @samp{.debug}.  Note -
+if compression would actually make a section @emph{larger} then it is
+not compressed or renamed. 
 
 @item --decompress-debug-sections
-Decompress DWARF debug sections using zlib.
+Decompress DWARF debug sections using zlib.  The original section
+names of the compressed sections are restored.
 
 @item -V
 @itemx --version
diff --git a/gas/ChangeLog b/gas/ChangeLog
index bccf7b3..7bf7794 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,12 @@
+2015-03-18  Jon Turney  <jon.turney@dronecode.org.uk>
+	    Nick Clifton  <nickc@redhat.com>
+
+	PR binutils/18087
+	* doc/as.texinfo: Note that when gas compresses debug sections the
+	compression is only performed if it makes the section smaller.
+	* write.c (compress_debug): Do not compress a debug section if
+	doing so would make it larger.
+
 2015-03-17  Ganesh Gopalasubramanian  <Ganesh.Gopalasubramanian@amd.com>
 
 	* config/tc-i386.c (cpu_arch): Add PROCESSOR_ZNVER flags.
diff --git a/gas/doc/as.texinfo b/gas/doc/as.texinfo
index 36c2207..bedb4d5 100644
--- a/gas/doc/as.texinfo
+++ b/gas/doc/as.texinfo
@@ -627,7 +627,8 @@ Begin in alternate macro mode.
 @item --compress-debug-sections
 Compress DWARF debug sections using zlib.  The debug sections are renamed
 to begin with @samp{.zdebug}, and the resulting object file may not be
-compatible with older linkers and object file utilities.
+compatible with older linkers and object file utilities.  Note if compression
+would make a given section @emph{larger} then it is not compressed or renamed.
 
 @item --nocompress-debug-sections
 Do not compress DWARF debug sections.  This is the default.
diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog
index 3b58c97..5b16085 100644
--- a/gas/testsuite/ChangeLog
+++ b/gas/testsuite/ChangeLog
@@ -1,3 +1,10 @@
+2015-03-18  Jon Turney  <jon.turney@dronecode.org.uk>
+	    Nick Clifton  <nickc@redhat.com>
+
+	PR binutils/18087
+	* gas/i386/dw2-compress-1.d: Do not expect the .debug_abbrev or
+	.debug_info sections to be compressed.
+
 2015-03-17  Ganesh Gopalasubramanian  <Ganesh.Gopalasubramanian@amd.com>
 
 	* gas/i386/i386.exp: Add new znver1 test cases.
diff --git a/gas/testsuite/gas/i386/dw2-compress-1.d b/gas/testsuite/gas/i386/dw2-compress-1.d
index 4d1a393..2b2fd8d 100644
--- a/gas/testsuite/gas/i386/dw2-compress-1.d
+++ b/gas/testsuite/gas/i386/dw2-compress-1.d
@@ -2,7 +2,7 @@
 #readelf: -w
 #name: DWARF2 debugging information 1
 
-Contents of the .zdebug_info section:
+Contents of the .debug_info section:
 
   Compilation Unit @ offset 0x0:
    Length:        0x4e \(32-bit\)
@@ -31,7 +31,7 @@ Contents of the .zdebug_info section:
     <50>   DW_AT_encoding    : 5	\(signed\)
  <1><51>: Abbrev Number: 0
 
-Contents of the .zdebug_abbrev section:
+Contents of the .debug_abbrev section:
 
   Number TAG \(0x0\)
    1      DW_TAG_compile_unit    \[has children\]
diff --git a/gas/write.c b/gas/write.c
index 949ae92..e3570ac 100644
--- a/gas/write.c
+++ b/gas/write.c
@@ -1526,6 +1526,11 @@ compress_debug (bfd *abfd, asection *sec, void *xxx ATTRIBUTE_UNUSED)
 	break;
     }
 
+  /* PR binutils/18087: If compression didn't make
+     the section smaller, just keep it uncompressed.  */
+  if (compressed_size > sec->size)
+    return;
+  
   /* Replace the uncompressed frag list with the compressed frag list.  */
   seginfo->frchainP->frch_root = first_newf;
   seginfo->frchainP->frch_last = last_newf;



More information about the Binutils-cvs mailing list