From 273a49858fa9c8d73de87167618ef99d70f9731a Mon Sep 17 00:00:00 2001 From: Jon Turney Date: Wed, 18 Mar 2015 15:47:13 +0000 Subject: [PATCH] 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. --- 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 9173e17fcb..c5f109e161 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,14 @@ +2015-03-18 Jon Turney + Nick Clifton + + 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 * elf64-ppc.c (ppc64_elf_get_synthetic_symtab): Return count of 0 diff --git a/bfd/coffgen.c b/bfd/coffgen.c index 5c664a49f2..b1ab56e2e1 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 0087a665d8..ad1fbee013 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 13d4272c93..c4defda728 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 f59c0d1359..5c0efb115f 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,11 @@ +2015-03-18 Jon Turney + Nick Clifton + + 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 PR binutils/18101 diff --git a/binutils/doc/binutils.texi b/binutils/doc/binutils.texi index 22d54bebfe..da50163ce4 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 bccf7b30d6..7bf7794f5d 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,12 @@ +2015-03-18 Jon Turney + Nick Clifton + + 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 * config/tc-i386.c (cpu_arch): Add PROCESSOR_ZNVER flags. diff --git a/gas/doc/as.texinfo b/gas/doc/as.texinfo index 36c2207c3e..bedb4d5a54 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 3b58c97f61..5b1608521e 100644 --- a/gas/testsuite/ChangeLog +++ b/gas/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2015-03-18 Jon Turney + Nick Clifton + + 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 * 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 4d1a393a2a..2b2fd8d928 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 949ae921df..e3570acace 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; -- 2.34.1