diff options
author | Mark Wielaard <mark@klomp.org> | 2018-11-27 11:59:10 +0000 |
---|---|---|
committer | Nick Clifton <nickc@redhat.com> | 2018-11-27 11:59:10 +0000 |
commit | 4207142d6a5d2359170c5f9a140fc1a2351fbda9 (patch) | |
tree | a2d367ab1675c2d4206e10943a8e0ea9c7904784 /bfd/bfd.c | |
parent | 6a75ea85b19306046e04a08eec344ec67ec2733d (diff) | |
download | gdb-4207142d6a5d2359170c5f9a140fc1a2351fbda9.zip gdb-4207142d6a5d2359170c5f9a140fc1a2351fbda9.tar.gz gdb-4207142d6a5d2359170c5f9a140fc1a2351fbda9.tar.bz2 |
Handle ELF compressed header alignment correctly by setting up the section alignment correctly for the Elf32_Chdr or Elf64_Chdr type and respect the ch_addralign field when decompressing the section data.
PR binutils/23919
binutils* readelf.c (dump_sections_as_strings): Remove bogus addralign check.
(dump_sections_as_bytes): Likewise.
(load_specific_debug_sections): Likewise.
* testsuite/binutils-all/dw2-3.rS: Adjust alignment.
* testsuite/binutils-all/dw2-3.rt: Likewise.
bfd * bfd.c (bfd_update_compression_header): Explicitly set alignment.
(bfd_check_compression_header): Add uncompressed_alignment_power
argument. Check ch_addralign is a power of 2.
* bfd-in2.h: Regenerated.
* compress.c (bfd_compress_section_contents): Get and set
orig_uncompressed_alignment_pow if section is decompressed.
(bfd_is_section_compressed_with_header): Add and get
uncompressed_align_pow_p argument.
(bfd_is_section_compressed): Add uncompressed_align_power argument
to bfd_is_section_compressed_with_header call.
(bfd_init_section_decompress_status): Get and set
uncompressed_alignment_power.
* elf.c (_bfd_elf_make_section_from_shdr): Add
uncompressed_align_power argument to
bfd_is_section_compressed_with_header call.
Diffstat (limited to 'bfd/bfd.c')
-rw-r--r-- | bfd/bfd.c | 20 |
1 files changed, 15 insertions, 5 deletions
@@ -2332,6 +2332,8 @@ bfd_update_compression_header (bfd *abfd, bfd_byte *contents, bfd_put_32 (abfd, sec->size, &echdr->ch_size); bfd_put_32 (abfd, 1 << sec->alignment_power, &echdr->ch_addralign); + /* bfd_log2 (alignof (Elf32_Chdr)) */ + bfd_set_section_alignment (abfd, sec, 2); } else { @@ -2342,6 +2344,8 @@ bfd_update_compression_header (bfd *abfd, bfd_byte *contents, bfd_put_64 (abfd, sec->size, &echdr->ch_size); bfd_put_64 (abfd, 1 << sec->alignment_power, &echdr->ch_addralign); + /* bfd_log2 (alignof (Elf64_Chdr)) */ + bfd_set_section_alignment (abfd, sec, 3); } } else @@ -2354,6 +2358,8 @@ bfd_update_compression_header (bfd *abfd, bfd_byte *contents, order. */ memcpy (contents, "ZLIB", 4); bfd_putb64 (sec->size, contents + 4); + /* No way to keep the original alignment, just use 1 always. */ + bfd_set_section_alignment (abfd, sec, 0); } } } @@ -2368,12 +2374,14 @@ 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, + unsigned int *uncompressed_alignment_power); DESCRIPTION Check the compression header at CONTENTS of SEC in ABFD and - store the uncompressed size in UNCOMPRESSED_SIZE if the - compression header is valid. + store the uncompressed size in UNCOMPRESSED_SIZE and the + uncompressed data alignment in UNCOMPRESSED_ALIGNMENT_POWER + if the compression header is valid. RETURNS Return TRUE if the compression header is valid. @@ -2382,7 +2390,8 @@ RETURNS bfd_boolean bfd_check_compression_header (bfd *abfd, bfd_byte *contents, asection *sec, - bfd_size_type *uncompressed_size) + bfd_size_type *uncompressed_size, + unsigned int *uncompressed_alignment_power) { if (bfd_get_flavour (abfd) == bfd_target_elf_flavour && (elf_section_flags (sec) & SHF_COMPRESSED) != 0) @@ -2404,9 +2413,10 @@ bfd_check_compression_header (bfd *abfd, bfd_byte *contents, chdr.ch_addralign = bfd_get_64 (abfd, &echdr->ch_addralign); } if (chdr.ch_type == ELFCOMPRESS_ZLIB - && chdr.ch_addralign == 1U << sec->alignment_power) + && chdr.ch_addralign == (1U << bfd_log2 (chdr.ch_addralign))) { *uncompressed_size = chdr.ch_size; + *uncompressed_alignment_power = bfd_log2 (chdr.ch_addralign); return TRUE; } } |