From dab394de9e41de54df5e2310e081e1c550326f5b Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Thu, 14 May 2015 15:58:51 -0700 Subject: [PATCH] Don't add the zlib header to SHF_COMPRESSED section In a SHF_COMPRESSED compressed section, the raw compressed data should begin immediately after the compression header. This patch removes the extra zlib header from the SHF_COMPRESSED section. bfd/ * bfd.c (bfd_update_compression_header): Also write the zlib header if the SHF_COMPRESSED bit cleared.. (bfd_check_compression_header): Return the uncompressed size. * compress.c (decompress_contents): Don't skip the zlib header. (bfd_compress_section_contents): Properly handle ELFCOMPRESS_ZLIB, which doesn't have the zlib header. (bfd_init_section_decompress_status): Likewise. (bfd_get_full_section_contents): Updated. (bfd_is_section_compressed): Likewise. (bfd_is_section_compressed_with_header): Return the uncompressed size. * elf.c (_bfd_elf_make_section_from_shdr): Updated. * bfd-in2.h: Regenerated. binutils/ * readelf.c (uncompress_section_contents): Add a parameter for uncompressed size. Don't check the zlib header. (load_specific_debug_section): Updated. binutils/testsuite/ * binutils-all/compress.exp: Replace "$OBJDUMP -s -j .debug_info" with "$OBJDUMP -W". * binutils-all/libdw2-compressedgabi.out: Updated. gas/ 2015-05-14 H.J. Lu * write.c (compress_debug): Don't write the zlib header, which is handled by bfd_update_compression_header. --- bfd/ChangeLog | 16 + bfd/bfd-in2.h | 5 +- bfd/bfd.c | 30 +- bfd/compress.c | 157 ++++----- bfd/elf.c | 5 +- binutils/ChangeLog | 6 + binutils/readelf.c | 46 +-- binutils/testsuite/ChangeLog | 6 + binutils/testsuite/binutils-all/compress.exp | 3 +- .../binutils-all/libdw2-compressedgabi.out | 363 ++++++++++++++++++++- gas/ChangeLog | 5 + gas/write.c | 25 +- 12 files changed, 544 insertions(+), 123 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 9ef7a5d..3cc8839 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,19 @@ +2015-05-14 H.J. Lu + + * bfd.c (bfd_update_compression_header): Also write the zlib + header if the SHF_COMPRESSED bit cleared.. + (bfd_check_compression_header): Return the uncompressed size. + * compress.c (decompress_contents): Don't skip the zlib header. + (bfd_compress_section_contents): Properly handle ELFCOMPRESS_ZLIB, + which doesn't have the zlib header. + (bfd_init_section_decompress_status): Likewise. + (bfd_get_full_section_contents): Updated. + (bfd_is_section_compressed): Likewise. + (bfd_is_section_compressed_with_header): Return the uncompressed + size. + * elf.c (_bfd_elf_make_section_from_shdr): Updated. + * bfd-in2.h: Regenerated. + 2015-05-14 Jiong Wang * elfnn-aarch64.c (elfNN_aarch64_relocate_section): Remove overflow diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index ade49ff..6f7ae34 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -6816,7 +6816,7 @@ void bfd_update_compression_header bfd_boolean bfd_check_compression_header (bfd *abfd, bfd_byte *contents, asection *sec, - bfd_size_type uncompressed_size); + bfd_size_type *uncompressed_size); int bfd_get_compression_header_size (bfd *abfd, asection *sec); @@ -7334,7 +7334,8 @@ void bfd_cache_section_contents bfd_boolean bfd_is_section_compressed_with_header (bfd *abfd, asection *section, - int *compression_header_size_p); + int *compression_header_size_p, + bfd_size_type *uncompressed_size_p); bfd_boolean bfd_is_section_compressed (bfd *abfd, asection *section); diff --git a/bfd/bfd.c b/bfd/bfd.c index 5b336a9..ab410cb 100644 --- a/bfd/bfd.c +++ b/bfd/bfd.c @@ -1998,8 +1998,16 @@ bfd_update_compression_header (bfd *abfd, bfd_byte *contents, } } else - /* Clear the SHF_COMPRESSED bit. */ - elf_section_flags (sec) &= ~SHF_COMPRESSED; + { + /* Clear the SHF_COMPRESSED bit. */ + elf_section_flags (sec) &= ~SHF_COMPRESSED; + + /* Write the zlib header. It should be "ZLIB" followed by + the uncompressed section size, 8 bytes in big-endian + order. */ + memcpy (contents, "ZLIB", 4); + bfd_putb64 (sec->size, contents + 4); + } } } else @@ -2013,11 +2021,12 @@ bfd_update_compression_header (bfd *abfd, bfd_byte *contents, SYNOPSIS bfd_boolean bfd_check_compression_header (bfd *abfd, bfd_byte *contents, asection *sec, - bfd_size_type uncompressed_size); + bfd_size_type *uncompressed_size); DESCRIPTION - Check the compression header at CONTENTS of SEC in ABFD with - the uncompressed size UNCOMPRESSED_SIZE. + Check the compression header at CONTENTS of SEC in ABFD and + store the uncompressed size in UNCOMPRESSED_SIZE if the + compression header is valid. RETURNS Return TRUE if the compression header is valid. @@ -2026,7 +2035,7 @@ RETURNS bfd_boolean bfd_check_compression_header (bfd *abfd, bfd_byte *contents, asection *sec, - bfd_size_type uncompressed_size) + bfd_size_type *uncompressed_size) { if (bfd_get_flavour (abfd) == bfd_target_elf_flavour && (elf_section_flags (sec) & SHF_COMPRESSED) != 0) @@ -2047,9 +2056,12 @@ bfd_check_compression_header (bfd *abfd, bfd_byte *contents, chdr.ch_size = bfd_get_64 (abfd, &echdr->ch_size); chdr.ch_addralign = bfd_get_64 (abfd, &echdr->ch_addralign); } - return (chdr.ch_type == ELFCOMPRESS_ZLIB - && chdr.ch_size == uncompressed_size - && chdr.ch_addralign == 1U << sec->alignment_power); + if (chdr.ch_type == ELFCOMPRESS_ZLIB + && chdr.ch_addralign == 1U << sec->alignment_power) + { + *uncompressed_size = chdr.ch_size; + return TRUE; + } } return FALSE; diff --git a/bfd/compress.c b/bfd/compress.c index 07289e5..7751948 100644 --- a/bfd/compress.c +++ b/bfd/compress.c @@ -43,8 +43,8 @@ decompress_contents (bfd_byte *compressed_buffer, we first zero the entire z_stream structure and then set the fields that we need. */ memset (& strm, 0, sizeof strm); - strm.avail_in = compressed_size - 12; - strm.next_in = (Bytef*) compressed_buffer + 12; + strm.avail_in = compressed_size; + strm.next_in = (Bytef*) compressed_buffer; strm.avail_out = uncompressed_size; BFD_ASSERT (Z_OK == 0); @@ -81,18 +81,19 @@ bfd_compress_section_contents (bfd *abfd, sec_ptr sec, bfd_byte *buffer; bfd_size_type buffer_size; bfd_boolean decompress; -#if defined(__GNUC__) && GCC_VERSION < 4007 - /* Work around a GCC uninitialized warning bug fixed in GCC 4.7. */ int zlib_size = 0; -#else - int zlib_size; -#endif int orig_compression_header_size; - int compression_header_size - = bfd_get_compression_header_size (abfd, NULL); + bfd_size_type orig_uncompressed_size; + int header_size = bfd_get_compression_header_size (abfd, NULL); bfd_boolean compressed = bfd_is_section_compressed_with_header (abfd, sec, - &orig_compression_header_size); + &orig_compression_header_size, + &orig_uncompressed_size); + + /* Either ELF compression header or the 12-byte, "ZLIB" + 8-byte size, + overhead in .zdebug* section. */ + if (!header_size) + header_size = 12; if (compressed) { @@ -105,34 +106,34 @@ bfd_compress_section_contents (bfd *abfd, sec_ptr sec, if (orig_compression_header_size == 0) { /* Convert it from .zdebug* section. Get the uncompressed - size first. */ - zlib_size = uncompressed_size; - compressed_size = zlib_size + compression_header_size; - uncompressed_size = bfd_getb64 (uncompressed_buffer + 4); + size first. We need to substract the 12-byte overhead in + .zdebug* section. Set orig_compression_header_size to + the 12-bye overhead. */ + orig_compression_header_size = 12; + zlib_size = uncompressed_size - 12; } else { - /* Convert it to .zdebug* section. */ + /* Convert it to .zdebug* section. */ zlib_size = uncompressed_size - orig_compression_header_size; - compressed_size = zlib_size; } + + /* Add the header size. */ + compressed_size = zlib_size + header_size; } else - compressed_size = compressBound (uncompressed_size) + 12; + compressed_size = compressBound (uncompressed_size) + header_size; - /* When converting from .zdebug* section, uncompress if it leads to - smaller size. */ - if (compressed - && orig_compression_header_size == 0 - && compressed_size > uncompressed_size) + /* Uncompress if it leads to smaller size. */ + if (compressed && compressed_size > orig_uncompressed_size) { decompress = TRUE; - buffer_size = uncompressed_size; + buffer_size = orig_uncompressed_size; } else { decompress = FALSE; - buffer_size = compressed_size + compression_header_size; + buffer_size = compressed_size; } buffer = (bfd_byte *) bfd_alloc (abfd, buffer_size); if (buffer == NULL) @@ -140,11 +141,12 @@ bfd_compress_section_contents (bfd *abfd, sec_ptr sec, if (compressed) { - sec->size = uncompressed_size; + sec->size = orig_uncompressed_size; if (decompress) { - if (!decompress_contents (uncompressed_buffer, zlib_size, - buffer, uncompressed_size)) + if (!decompress_contents (uncompressed_buffer + + orig_compression_header_size, + zlib_size, buffer, buffer_size)) { bfd_set_error (bfd_error_bad_value); bfd_release (abfd, buffer); @@ -153,20 +155,18 @@ bfd_compress_section_contents (bfd *abfd, sec_ptr sec, free (uncompressed_buffer); sec->contents = buffer; sec->compress_status = COMPRESS_SECTION_DONE; - return uncompressed_size; + return orig_uncompressed_size; } else { bfd_update_compression_header (abfd, buffer, sec); - memmove (buffer + compression_header_size, + memmove (buffer + header_size, uncompressed_buffer + orig_compression_header_size, zlib_size); } } else { - bfd_size_type size = uncompressed_size; - int header_size = 12 + compression_header_size; if (compress ((Bytef*) buffer + header_size, &compressed_size, (const Bytef*) uncompressed_buffer, @@ -181,15 +181,7 @@ bfd_compress_section_contents (bfd *abfd, sec_ptr sec, /* PR binutils/18087: If compression didn't make the section smaller, just keep it uncompressed. */ if (compressed_size < uncompressed_size) - { - bfd_update_compression_header (abfd, buffer, sec); - - /* Write the zlib header. In this case, it should be "ZLIB" - followed by the uncompressed section size, 8 bytes in - big-endian order. */ - memcpy (buffer + compression_header_size, "ZLIB", 4); - bfd_putb64 (size, buffer + compression_header_size + 4); - } + bfd_update_compression_header (abfd, buffer, sec); else { /* NOTE: There is a small memory leak here since @@ -295,6 +287,10 @@ bfd_get_full_section_contents (bfd *abfd, sec_ptr sec, bfd_byte **ptr) goto fail_compressed; compression_header_size = bfd_get_compression_header_size (abfd, sec); + if (compression_header_size == 0) + /* Set header size to the zlib header size if it is a + SHF_COMPRESSED section. */ + compression_header_size = 12; if (!decompress_contents (compressed_buffer + compression_header_size, sec->compressed_size, p, sz)) { @@ -359,49 +355,56 @@ FUNCTION SYNOPSIS bfd_boolean bfd_is_section_compressed_with_header (bfd *abfd, asection *section, - int *compression_header_size_p); + int *compression_header_size_p, + bfd_size_type *uncompressed_size_p); DESCRIPTION Return @code{TRUE} if @var{section} is compressed. Compression - header size is returned in @var{compression_header_size_p}. If + header size is returned in @var{compression_header_size_p} and + uncompressed size is returned in @var{uncompressed_size_p}. If compression is unsupported, compression header size is returned - with -1. + with -1 and uncompressed size is returned with 0. */ bfd_boolean bfd_is_section_compressed_with_header (bfd *abfd, sec_ptr sec, - int *compression_header_size_p) + int *compression_header_size_p, + bfd_size_type *uncompressed_size_p) { - bfd_byte header[MAX_COMPRESSION_HEADER_SIZE + 12]; + bfd_byte header[MAX_COMPRESSION_HEADER_SIZE]; int compression_header_size; - int header_size = 12; + int header_size; unsigned int saved = sec->compress_status; bfd_boolean compressed; compression_header_size = bfd_get_compression_header_size (abfd, sec); if (compression_header_size > MAX_COMPRESSION_HEADER_SIZE) abort (); - header_size += compression_header_size; + header_size = compression_header_size ? compression_header_size : 12; /* Don't decompress the section. */ sec->compress_status = COMPRESS_SECTION_NONE; - /* Read the zlib header. In this case, it should be "ZLIB" followed - by the uncompressed section size, 8 bytes in big-endian order. */ - compressed = bfd_get_section_contents (abfd, sec, header, 0, - header_size) - && CONST_STRNEQ ((char*) header + compression_header_size, - "ZLIB"); + /* Read the header. */ + if (bfd_get_section_contents (abfd, sec, header, 0, header_size)) + { + if (compression_header_size == 0) + /* In this case, it should be "ZLIB" followed by the uncompressed + section size, 8 bytes in big-endian order. */ + compressed = CONST_STRNEQ ((char*) header , "ZLIB"); + else + compressed = TRUE; + } + else + compressed = FALSE; + *uncompressed_size_p = sec->size; if (compressed) { if (compression_header_size != 0) { - bfd_size_type uncompressed_size - = bfd_getb64 ((bfd_byte *) header - + compression_header_size + 4); if (!bfd_check_compression_header (abfd, header, sec, - uncompressed_size)) + uncompressed_size_p)) compression_header_size = -1; } /* Check for the pathalogical case of a debug string section that @@ -409,8 +412,10 @@ bfd_is_section_compressed_with_header (bfd *abfd, sec_ptr sec, no uncompressed .debug_str section would ever be big enough to have the first byte of its (big-endian) size be non-zero. */ else if (strcmp (sec->name, ".debug_str") == 0 - && ISPRINT (header[compression_header_size + 4])) + && ISPRINT (header[4])) compressed = FALSE; + else + *uncompressed_size_p = bfd_getb64 (header + 4); } /* Restore compress_status. */ @@ -435,9 +440,12 @@ bfd_boolean bfd_is_section_compressed (bfd *abfd, sec_ptr sec) { int compression_header_size; + bfd_size_type uncompressed_size; return (bfd_is_section_compressed_with_header (abfd, sec, - &compression_header_size) - && compression_header_size >= 0); + &compression_header_size, + &uncompressed_size) + && compression_header_size >= 0 + && uncompressed_size > 0); } /* @@ -460,16 +468,17 @@ DESCRIPTION bfd_boolean bfd_init_section_decompress_status (bfd *abfd, sec_ptr sec) { - bfd_byte header[MAX_COMPRESSION_HEADER_SIZE + 12]; + bfd_byte header[MAX_COMPRESSION_HEADER_SIZE]; int compression_header_size; - int header_size = 12; + int header_size; bfd_size_type uncompressed_size; compression_header_size = bfd_get_compression_header_size (abfd, sec); if (compression_header_size > MAX_COMPRESSION_HEADER_SIZE) abort (); - header_size += compression_header_size; + header_size = compression_header_size ? compression_header_size : 12; + /* Read the header. */ if (sec->rawsize != 0 || sec->contents != NULL || sec->compress_status != COMPRESS_SECTION_NONE @@ -479,22 +488,24 @@ bfd_init_section_decompress_status (bfd *abfd, sec_ptr sec) return FALSE; } - /* Read the zlib header. In this case, it should be "ZLIB" followed - by the uncompressed section size, 8 bytes in big-endian order. */ - if (! CONST_STRNEQ ((char*) header + compression_header_size, "ZLIB")) + if (compression_header_size == 0) { - bfd_set_error (bfd_error_wrong_format); - return FALSE; + /* In this case, it should be "ZLIB" followed by the uncompressed + section size, 8 bytes in big-endian order. */ + if (! CONST_STRNEQ ((char*) header, "ZLIB")) + { + bfd_set_error (bfd_error_wrong_format); + return FALSE; + } + uncompressed_size = bfd_getb64 (header + 4); } - - uncompressed_size = bfd_getb64 (header + compression_header_size + 4); - if (compression_header_size != 0 - && !bfd_check_compression_header (abfd, header, sec, - uncompressed_size)) + else if (!bfd_check_compression_header (abfd, header, sec, + &uncompressed_size)) { bfd_set_error (bfd_error_wrong_format); return FALSE; } + sec->compressed_size = sec->size; sec->size = uncompressed_size; sec->compress_status = DECOMPRESS_SECTION_SIZED; diff --git a/bfd/elf.c b/bfd/elf.c index dbdc474..619a640 100644 --- a/bfd/elf.c +++ b/bfd/elf.c @@ -1067,9 +1067,11 @@ _bfd_elf_make_section_from_shdr (bfd *abfd, { enum { nothing, compress, decompress } action = nothing; int compression_header_size; + bfd_size_type uncompressed_size; bfd_boolean compressed = bfd_is_section_compressed_with_header (abfd, newsect, - &compression_header_size); + &compression_header_size, + &uncompressed_size); if (compressed) { @@ -1085,6 +1087,7 @@ _bfd_elf_make_section_from_shdr (bfd *abfd, if (newsect->size != 0 && (abfd->flags & BFD_COMPRESS) && compression_header_size >= 0 + && uncompressed_size > 0 && (!compressed || ((compression_header_size > 0) != ((abfd->flags & BFD_COMPRESS_GABI) != 0)))) diff --git a/binutils/ChangeLog b/binutils/ChangeLog index 333a82d..db01e39 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,9 @@ +2015-05-14 H.J. Lu + + * readelf.c (uncompress_section_contents): Add a parameter for + uncompressed size. Don't check the zlib header. + (load_specific_debug_section): Updated. + 2015-05-13 H.J. Lu * elfedit.c (elf_class): Return ELF_CLASS_BOTH by default. diff --git a/binutils/readelf.c b/binutils/readelf.c index c2531ed..e7090ff 100644 --- a/binutils/readelf.c +++ b/binutils/readelf.c @@ -12074,30 +12074,14 @@ dump_section_as_bytes (Elf_Internal_Shdr * section, static int uncompress_section_contents (unsigned char **buffer, + dwarf_size_type uncompressed_size, dwarf_size_type *size) { dwarf_size_type compressed_size = *size; unsigned char * compressed_buffer = *buffer; - dwarf_size_type uncompressed_size; unsigned char * uncompressed_buffer; z_stream strm; int rc; - dwarf_size_type header_size = 12; - - /* Read the zlib header. In this case, it should be "ZLIB" followed - by the uncompressed section size, 8 bytes in big-endian order. */ - if (compressed_size < header_size - || ! streq ((char *) compressed_buffer, "ZLIB")) - return 0; - - uncompressed_size = compressed_buffer[4]; uncompressed_size <<= 8; - uncompressed_size += compressed_buffer[5]; uncompressed_size <<= 8; - uncompressed_size += compressed_buffer[6]; uncompressed_size <<= 8; - uncompressed_size += compressed_buffer[7]; uncompressed_size <<= 8; - uncompressed_size += compressed_buffer[8]; uncompressed_size <<= 8; - uncompressed_size += compressed_buffer[9]; uncompressed_size <<= 8; - uncompressed_size += compressed_buffer[10]; uncompressed_size <<= 8; - uncompressed_size += compressed_buffer[11]; /* It is possible the section consists of several compressed buffers concatenated together, so we uncompress in a loop. */ @@ -12107,8 +12091,8 @@ uncompress_section_contents (unsigned char **buffer, we first zero the entire z_stream structure and then set the fields that we need. */ memset (& strm, 0, sizeof strm); - strm.avail_in = compressed_size - header_size; - strm.next_in = (Bytef *) compressed_buffer + header_size; + strm.avail_in = compressed_size; + strm.next_in = (Bytef *) compressed_buffer; strm.avail_out = uncompressed_size; uncompressed_buffer = (unsigned char *) xmalloc (uncompressed_size); @@ -12163,6 +12147,7 @@ load_specific_debug_section (enum dwarf_section_display_enum debug, { unsigned char *start = section->start; dwarf_size_type size = sec->sh_size; + dwarf_size_type uncompressed_size = 0; if ((sec->sh_flags & SHF_COMPRESSED) != 0) { @@ -12172,11 +12157,30 @@ load_specific_debug_section (enum dwarf_section_display_enum debug, if (chdr.ch_type != ELFCOMPRESS_ZLIB || chdr.ch_addralign != sec->sh_addralign) return 0; + uncompressed_size = chdr.ch_size; start += compression_header_size; size -= compression_header_size; } - - if (uncompress_section_contents (&start, &size)) + else if (size > 12 && streq ((char *) start, "ZLIB")) + { + /* Read the zlib header. In this case, it should be "ZLIB" + followed by the uncompressed section size, 8 bytes in + big-endian order. */ + uncompressed_size = start[4]; uncompressed_size <<= 8; + uncompressed_size += start[5]; uncompressed_size <<= 8; + uncompressed_size += start[6]; uncompressed_size <<= 8; + uncompressed_size += start[7]; uncompressed_size <<= 8; + uncompressed_size += start[8]; uncompressed_size <<= 8; + uncompressed_size += start[9]; uncompressed_size <<= 8; + uncompressed_size += start[10]; uncompressed_size <<= 8; + uncompressed_size += start[11]; + start += 12; + size -= 12; + } + + if (uncompressed_size + && uncompress_section_contents (&start, uncompressed_size, + &size)) { /* Free the compressed buffer, update the section buffer and the section size if uncompress is successful. */ diff --git a/binutils/testsuite/ChangeLog b/binutils/testsuite/ChangeLog index 07dad22..8b1e3b4 100644 --- a/binutils/testsuite/ChangeLog +++ b/binutils/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2015-05-14 H.J. Lu + + * binutils-all/compress.exp: Replace "$OBJDUMP -s -j .debug_info" + with "$OBJDUMP -W". + * binutils-all/libdw2-compressedgabi.out: Updated. + 2015-05-12 H.J. Lu * binutils-all/elfedit-1.d: Also skip x86_64-*-nacl*. diff --git a/binutils/testsuite/binutils-all/compress.exp b/binutils/testsuite/binutils-all/compress.exp index 8787e77..43a3ce1 100644 --- a/binutils/testsuite/binutils-all/compress.exp +++ b/binutils/testsuite/binutils-all/compress.exp @@ -544,8 +544,7 @@ set got [binutils_run $OBJCOPY "--compress-debug-sections=zlib-gabi ${copyfile}g if ![string match "" $got] then { fail "objcopy ($testname)" } else { - set got [remote_exec host "$OBJDUMP -s -j .debug_info - ${compressedcopyfile}gabi.a" "" "/dev/null" "tmpdir/libdw2-compressedgabi.out"] + set got [remote_exec host "$OBJDUMP -W ${compressedcopyfile}gabi.a" "" "/dev/null" "tmpdir/libdw2-compressedgabi.out"] if { [lindex $got 0] != 0 || ![string match "" [lindex $got 1]] } then { fail "$testname (reason: unexpected output)" diff --git a/binutils/testsuite/binutils-all/libdw2-compressedgabi.out b/binutils/testsuite/binutils-all/libdw2-compressedgabi.out index 3d395e4..3baa42a 100644 --- a/binutils/testsuite/binutils-all/libdw2-compressedgabi.out +++ b/binutils/testsuite/binutils-all/libdw2-compressedgabi.out @@ -1,3 +1,362 @@ -#... - .*ZLIB.* +In archive tmpdir/dw2-copy-compressedgabi.a: + +dw2-1-compressedgabi.o: +file format .* + +Contents of the .debug_info section: + + Compilation Unit @ offset 0x0: + Length: 0x4e \(32-bit\) + Version: 2 + Abbrev Offset: 0x0 + Pointer Size: 4 + <0>: Abbrev Number: 1 \(DW_TAG_compile_unit\) + DW_AT_stmt_list : 0x0 + <10> DW_AT_high_pc : 0x. + <14> DW_AT_low_pc : 0x. + <18> DW_AT_name : file1.txt + <22> DW_AT_producer : GNU C 3.3.3 + <2e> DW_AT_language : 1 \(ANSI C\) + <1><2f>: Abbrev Number: 2 \(DW_TAG_subprogram\) + <30> DW_AT_external : 1 + <31> DW_AT_decl_file : 1 + <32> DW_AT_decl_line : 2 + <33> DW_AT_name : func_cu1 + <3c> DW_AT_type : <0x4a> + <40> DW_AT_low_pc : 0x. + <44> DW_AT_high_pc : 0x. + <48> DW_AT_frame_base : 1 byte block: 55 \(DW_OP_reg5 \([^()]*\)\) + <1><4a>: Abbrev Number: 3 \(DW_TAG_base_type\) + <4b> DW_AT_name : int + <4f> DW_AT_byte_size : 4 + <50> DW_AT_encoding : 5 \(signed\) + <1><51>: Abbrev Number: 0 + +Raw dump of debug contents of section .debug_line: + + Offset: 0x0 + Length: 62 + DWARF Version: 2 + Prologue Length: 35 + Minimum Instruction Length: 1 + Initial value of 'is_stmt': 1 + Line Base: 1 + Line Range: 1 + Opcode Base: 16 + + Opcodes: + Opcode 1 has 0 args + Opcode 2 has 1 args + Opcode 3 has 1 args + Opcode 4 has 1 args + Opcode 5 has 1 args + Opcode 6 has 0 args + Opcode 7 has 0 args + Opcode 8 has 0 args + Opcode 9 has 1 args + Opcode 10 has 0 args + Opcode 11 has 0 args + Opcode 12 has 1 args + Opcode 13 has 0 args + Opcode 14 has 0 args + Opcode 15 has 0 args + + The Directory Table is empty. + + The File Name Table \(offset 0x.*\): + Entry Dir Time Size Name + 1 0 0 0 file1.txt + + Line Number Statements: + \[0x.*\] Extended opcode 2: set Address to 0x4 + \[0x.*\] Advance Line by 3 to 4 + \[0x.*\] Copy + \[0x.*\] Copy + \[0x.*\] Extended opcode 2: set Address to 0x8 + \[0x.*\] Extended opcode 1: End of Sequence + + +Contents of the .debug_abbrev section: + + Number TAG \(0x0\) + 1 DW_TAG_compile_unit \[has children\] + DW_AT_stmt_list DW_FORM_data4 + DW_AT_high_pc DW_FORM_addr + DW_AT_low_pc DW_FORM_addr + DW_AT_name DW_FORM_string + DW_AT_producer DW_FORM_string + DW_AT_language DW_FORM_data1 + DW_AT value: 0 DW_FORM value: 0 + 2 DW_TAG_subprogram \[no children\] + DW_AT_external DW_FORM_flag + DW_AT_decl_file DW_FORM_data1 + DW_AT_decl_line DW_FORM_data1 + DW_AT_name DW_FORM_string + DW_AT_type DW_FORM_ref4 + DW_AT_low_pc DW_FORM_addr + DW_AT_high_pc DW_FORM_addr + DW_AT_frame_base DW_FORM_block1 + DW_AT value: 0 DW_FORM value: 0 + 3 DW_TAG_base_type \[no children\] + DW_AT_name DW_FORM_string + DW_AT_byte_size DW_FORM_data1 + DW_AT_encoding DW_FORM_data1 + DW_AT value: 0 DW_FORM value: 0 + +dw2-2-compressedgabi.o: +file format .* + +Contents of the .debug_info section: + + Compilation Unit @ offset 0x0: + Length: 0x4e \(32-bit\) + Version: 2 + Abbrev Offset: 0x0 + Pointer Size: 4 + <0>: Abbrev Number: 1 \(DW_TAG_compile_unit\) + DW_AT_stmt_list : 0x0 + <10> DW_AT_high_pc : 0x4 + <14> DW_AT_low_pc : 0x0 + <18> DW_AT_name : file1.txt + <22> DW_AT_producer : GNU C 3.3.3 + <2e> DW_AT_language : 1 \(ANSI C\) + <1><2f>: Abbrev Number: 2 \(DW_TAG_subprogram\) + <30> DW_AT_external : 1 + <31> DW_AT_decl_file : 1 + <32> DW_AT_decl_line : 2 + <33> DW_AT_name : func_cu2 + <3c> DW_AT_type : <0x4a> + <40> DW_AT_low_pc : 0x0 + <44> DW_AT_high_pc : 0x4 + <48> DW_AT_frame_base : 1 byte block: 55 \(DW_OP_reg5 \(.*\)\) + <1><4a>: Abbrev Number: 3 \(DW_TAG_base_type\) + <4b> DW_AT_name : int + <4f> DW_AT_byte_size : 4 + <50> DW_AT_encoding : 5 \(signed\) + <1><51>: Abbrev Number: 0 + +Raw dump of debug contents of section .debug_line: + + Offset: 0x0 + Length: 62 + DWARF Version: 2 + Prologue Length: 35 + Minimum Instruction Length: 1 + Initial value of 'is_stmt': 1 + Line Base: 1 + Line Range: 1 + Opcode Base: 16 + + Opcodes: + Opcode 1 has 0 args + Opcode 2 has 1 args + Opcode 3 has 1 args + Opcode 4 has 1 args + Opcode 5 has 1 args + Opcode 6 has 0 args + Opcode 7 has 0 args + Opcode 8 has 0 args + Opcode 9 has 1 args + Opcode 10 has 0 args + Opcode 11 has 0 args + Opcode 12 has 1 args + Opcode 13 has 0 args + Opcode 14 has 0 args + Opcode 15 has 0 args + + The Directory Table is empty. + + The File Name Table \(offset 0x1f\): + Entry Dir Time Size Name + 1 0 0 0 file1.txt + + Line Number Statements: + \[0x0000002d\] Extended opcode 2: set Address to 0x0 + \[0x00000034\] Advance Line by 3 to 4 + \[0x00000036\] Copy + \[0x00000037\] Copy + \[0x00000038\] Extended opcode 2: set Address to 0x4 + \[0x0000003f\] Extended opcode 1: End of Sequence + + +Contents of the .debug_abbrev section: + + Number TAG \(0x0\) + 1 DW_TAG_compile_unit \[has children\] + DW_AT_stmt_list DW_FORM_data4 + DW_AT_high_pc DW_FORM_addr + DW_AT_low_pc DW_FORM_addr + DW_AT_name DW_FORM_string + DW_AT_producer DW_FORM_string + DW_AT_language DW_FORM_data1 + DW_AT value: 0 DW_FORM value: 0 + 2 DW_TAG_subprogram \[no children\] + DW_AT_external DW_FORM_flag + DW_AT_decl_file DW_FORM_data1 + DW_AT_decl_line DW_FORM_data1 + DW_AT_name DW_FORM_string + DW_AT_type DW_FORM_ref4 + DW_AT_low_pc DW_FORM_addr + DW_AT_high_pc DW_FORM_addr + DW_AT_frame_base DW_FORM_block1 + DW_AT value: 0 DW_FORM value: 0 + 3 DW_TAG_base_type \[no children\] + DW_AT_name DW_FORM_string + DW_AT_byte_size DW_FORM_data1 + DW_AT_encoding DW_FORM_data1 + DW_AT value: 0 DW_FORM value: 0 + + +dw2-3-compressedgabi.o: +file format .* + +Contents of the .debug_info section: + + Compilation Unit @ offset 0x0: + Length: 0x5e \(32-bit\) + Version: 2 + Abbrev Offset: 0x0 + Pointer Size: 4 + <0>: Abbrev Number: 1 \(DW_TAG_compile_unit\) + DW_AT_stmt_list : 0x0 + <10> DW_AT_high_pc : 0x4 + <14> DW_AT_low_pc : 0x0 + <18> DW_AT_name : file1.txt + <22> DW_AT_producer : GNU C 3.3.3 + <2e> DW_AT_language : 1 \(ANSI C\) + <1><2f>: Abbrev Number: 2 \(DW_TAG_subprogram\) + <30> DW_AT_external : 1 + <31> DW_AT_decl_file : 1 + <32> DW_AT_decl_line : 2 + <33> DW_AT_name : func_cu1 + <3c> DW_AT_type : <0x85> + <40> DW_AT_low_pc : 0x0 + <44> DW_AT_high_pc : 0x4 + <48> DW_AT_frame_base : 1 byte block: 55 \(DW_OP_reg5 \([^()]*\)\) + <1><4a>: Abbrev Number: 3 \(DW_TAG_base_type\) + <4b> DW_AT_name : int1 + <50> DW_AT_byte_size : 4 + <51> DW_AT_encoding : 5 \(signed\) + <1><52>: Abbrev Number: 4 \(DW_TAG_const_type\) + <53> DW_AT_type : <0x4a> + <1><57>: Abbrev Number: 5 \(DW_TAG_variable\) + <58> DW_AT_name : one + <5c> DW_AT_type : <0x52> + <60> DW_AT_const_value : 1 + <1><61>: Abbrev Number: 0 + Compilation Unit @ offset 0x62: + Length: 0x37 \(32-bit\) + Version: 2 + Abbrev Offset: 0x45 + Pointer Size: 4 + <0><6d>: Abbrev Number: 1 \(DW_TAG_compile_unit\) + <6e> DW_AT_name : file1.txt + <78> DW_AT_producer : GNU C 3.3.3 + <84> DW_AT_language : 1 \(ANSI C\) + <1><85>: Abbrev Number: 2 \(DW_TAG_base_type\) + <86> DW_AT_name : int2 + <8b> DW_AT_byte_size : 4 + <8c> DW_AT_encoding : 5 \(signed\) + <1><8d>: Abbrev Number: 3 \(DW_TAG_const_type\) + <8e> DW_AT_type : <0x85> + <1><92>: Abbrev Number: 4 \(DW_TAG_variable\) + <93> DW_AT_name : two + <97> DW_AT_type : <0x8d> + <9b> DW_AT_const_value : 2 + <1><9c>: Abbrev Number: 0 + +Contents of the .debug_abbrev section: + + Number TAG \(0x0\) + 1 DW_TAG_compile_unit \[has children\] + DW_AT_stmt_list DW_FORM_data4 + DW_AT_high_pc DW_FORM_addr + DW_AT_low_pc DW_FORM_addr + DW_AT_name DW_FORM_string + DW_AT_producer DW_FORM_string + DW_AT_language DW_FORM_data1 + DW_AT value: 0 DW_FORM value: 0 + 2 DW_TAG_subprogram \[no children\] + DW_AT_external DW_FORM_flag + DW_AT_decl_file DW_FORM_data1 + DW_AT_decl_line DW_FORM_data1 + DW_AT_name DW_FORM_string + DW_AT_type DW_FORM_ref_addr + DW_AT_low_pc DW_FORM_addr + DW_AT_high_pc DW_FORM_addr + DW_AT_frame_base DW_FORM_block1 + DW_AT value: 0 DW_FORM value: 0 + 3 DW_TAG_base_type \[no children\] + DW_AT_name DW_FORM_string + DW_AT_byte_size DW_FORM_data1 + DW_AT_encoding DW_FORM_data1 + DW_AT value: 0 DW_FORM value: 0 + 4 DW_TAG_const_type \[no children\] + DW_AT_type DW_FORM_ref4 + DW_AT value: 0 DW_FORM value: 0 + 5 DW_TAG_variable \[no children\] + DW_AT_name DW_FORM_string + DW_AT_type DW_FORM_ref4 + DW_AT_const_value DW_FORM_data1 + DW_AT value: 0 DW_FORM value: 0 + Number TAG \(0x45\) + 1 DW_TAG_compile_unit \[has children\] + DW_AT_name DW_FORM_string + DW_AT_producer DW_FORM_string + DW_AT_language DW_FORM_data1 + DW_AT value: 0 DW_FORM value: 0 + 2 DW_TAG_base_type \[no children\] + DW_AT_name DW_FORM_string + DW_AT_byte_size DW_FORM_data1 + DW_AT_encoding DW_FORM_data1 + DW_AT value: 0 DW_FORM value: 0 + 3 DW_TAG_const_type \[no children\] + DW_AT_type DW_FORM_ref4 + DW_AT value: 0 DW_FORM value: 0 + 4 DW_TAG_variable \[no children\] + DW_AT_name DW_FORM_string + DW_AT_type DW_FORM_ref4 + DW_AT_const_value DW_FORM_data1 + DW_AT value: 0 DW_FORM value: 0 + +Raw dump of debug contents of section .debug_line: + + Offset: 0x0 + Length: 62 + DWARF Version: 2 + Prologue Length: 35 + Minimum Instruction Length: 1 + Initial value of 'is_stmt': 1 + Line Base: 1 + Line Range: 1 + Opcode Base: 16 + + Opcodes: + Opcode 1 has 0 args + Opcode 2 has 1 args + Opcode 3 has 1 args + Opcode 4 has 1 args + Opcode 5 has 1 args + Opcode 6 has 0 args + Opcode 7 has 0 args + Opcode 8 has 0 args + Opcode 9 has 1 args + Opcode 10 has 0 args + Opcode 11 has 0 args + Opcode 12 has 1 args + Opcode 13 has 0 args + Opcode 14 has 0 args + Opcode 15 has 0 args + + The Directory Table is empty. + + The File Name Table \(offset 0x1f\): + Entry Dir Time Size Name + 1 0 0 0 file1.txt + + Line Number Statements: + \[0x0000002d\] Extended opcode 2: set Address to 0x0 + \[0x00000034\] Advance Line by 3 to 4 + \[0x00000036\] Copy + \[0x00000037\] Copy + \[0x00000038\] Extended opcode 2: set Address to 0x4 + \[0x0000003f\] Extended opcode 1: End of Sequence + #pass diff --git a/gas/ChangeLog b/gas/ChangeLog index 683a30e..2b1d99c 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,8 @@ +2015-05-14 H.J. Lu + + * write.c (compress_debug): Don't write the zlib header, which + is handled by bfd_update_compression_header. + 2015-05-13 Max Filippov * config/tc-xtensa.c (xtensa_relax_frag): Allow trampoline to be diff --git a/gas/write.c b/gas/write.c index bc76962..894b271 100644 --- a/gas/write.c +++ b/gas/write.c @@ -1414,8 +1414,6 @@ compress_debug (bfd *abfd, asection *sec, void *xxx ATTRIBUTE_UNUSED) int x; flagword flags = bfd_get_section_flags (abfd, sec); unsigned int header_size, compression_header_size; - /* Maximimum compression header is 24 bytes. */ - bfd_byte compression_header[24]; if (seginfo == NULL || sec->size < 32 @@ -1431,14 +1429,20 @@ compress_debug (bfd *abfd, asection *sec, void *xxx ATTRIBUTE_UNUSED) return; if (flag_compress_debug == COMPRESS_DEBUG_GABI_ZLIB) - stdoutput->flags |= BFD_COMPRESS | BFD_COMPRESS_GABI; + { + stdoutput->flags |= BFD_COMPRESS | BFD_COMPRESS_GABI; + compression_header_size + = bfd_get_compression_header_size (stdoutput, NULL); + header_size = compression_header_size; + } else - stdoutput->flags |= BFD_COMPRESS; - compression_header_size - = bfd_get_compression_header_size (stdoutput, NULL); + { + stdoutput->flags |= BFD_COMPRESS; + compression_header_size = 0; + header_size = 12; + } - /* Create a new frag to contain the "ZLIB" header. */ - header_size = 12 + compression_header_size; + /* Create a new frag to contain the compression header. */ first_newf = frag_alloc (ob); if (obstack_room (ob) < header_size) first_newf = frag_alloc (ob); @@ -1533,11 +1537,6 @@ compress_debug (bfd *abfd, asection *sec, void *xxx ATTRIBUTE_UNUSED) if (compressed_size >= uncompressed_size) return; - if (compression_header_size) - memcpy (header, compression_header, compression_header_size); - memcpy (header + compression_header_size, "ZLIB", 4); - bfd_putb64 (uncompressed_size, header + compression_header_size + 4); - /* Replace the uncompressed frag list with the compressed frag list. */ seginfo->frchainP->frch_root = first_newf; seginfo->frchainP->frch_last = last_newf; -- 2.7.4