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.
This commit is contained in:
parent
6a75ea85b1
commit
4207142d6a
|
@ -1,3 +1,22 @@
|
|||
2018-11-27 Mark Wielaard <mark@klomp.org>
|
||||
|
||||
PR binutils/23919
|
||||
* 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.
|
||||
|
||||
2018-11-21 Jozef Lawrynowicz <jozef.l@mittosystems.com>
|
||||
|
||||
* elf32-msp430.c (elf32_msp430_merge_mspabi_attributes): Do not
|
||||
|
|
|
@ -7419,7 +7419,8 @@ 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,
|
||||
unsigned int *uncompressed_alignment_power);
|
||||
|
||||
int bfd_get_compression_header_size (bfd *abfd, asection *sec);
|
||||
|
||||
|
@ -8006,7 +8007,8 @@ void bfd_cache_section_contents
|
|||
bfd_boolean bfd_is_section_compressed_with_header
|
||||
(bfd *abfd, asection *section,
|
||||
int *compression_header_size_p,
|
||||
bfd_size_type *uncompressed_size_p);
|
||||
bfd_size_type *uncompressed_size_p,
|
||||
unsigned int *uncompressed_alignment_power_p);
|
||||
|
||||
bfd_boolean bfd_is_section_compressed
|
||||
(bfd *abfd, asection *section);
|
||||
|
|
20
bfd/bfd.c
20
bfd/bfd.c
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -84,11 +84,13 @@ bfd_compress_section_contents (bfd *abfd, sec_ptr sec,
|
|||
int zlib_size = 0;
|
||||
int orig_compression_header_size;
|
||||
bfd_size_type orig_uncompressed_size;
|
||||
unsigned int orig_uncompressed_alignment_pow;
|
||||
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_uncompressed_size);
|
||||
&orig_uncompressed_size,
|
||||
&orig_uncompressed_alignment_pow);
|
||||
|
||||
/* Either ELF compression header or the 12-byte, "ZLIB" + 8-byte size,
|
||||
overhead in .zdebug* section. */
|
||||
|
@ -153,6 +155,9 @@ bfd_compress_section_contents (bfd *abfd, sec_ptr sec,
|
|||
return 0;
|
||||
}
|
||||
free (uncompressed_buffer);
|
||||
bfd_set_section_alignment (abfd, sec,
|
||||
orig_uncompressed_alignment_pow);
|
||||
|
||||
sec->contents = buffer;
|
||||
sec->compress_status = COMPRESS_SECTION_DONE;
|
||||
return orig_uncompressed_size;
|
||||
|
@ -364,20 +369,24 @@ SYNOPSIS
|
|||
bfd_boolean bfd_is_section_compressed_with_header
|
||||
(bfd *abfd, asection *section,
|
||||
int *compression_header_size_p,
|
||||
bfd_size_type *uncompressed_size_p);
|
||||
bfd_size_type *uncompressed_size_p,
|
||||
unsigned int *uncompressed_alignment_power_p);
|
||||
|
||||
DESCRIPTION
|
||||
Return @code{TRUE} if @var{section} is compressed. Compression
|
||||
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 and uncompressed size is returned with 0.
|
||||
header size is returned in @var{compression_header_size_p},
|
||||
uncompressed size is returned in @var{uncompressed_size_p}
|
||||
and the uncompressed data alignement power is returned in
|
||||
@var{uncompressed_align_pow_p}. If compression is
|
||||
unsupported, compression header size is returned 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,
|
||||
bfd_size_type *uncompressed_size_p)
|
||||
bfd_size_type *uncompressed_size_p,
|
||||
unsigned int *uncompressed_align_pow_p)
|
||||
{
|
||||
bfd_byte header[MAX_COMPRESSION_HEADER_SIZE];
|
||||
int compression_header_size;
|
||||
|
@ -412,7 +421,8 @@ bfd_is_section_compressed_with_header (bfd *abfd, sec_ptr sec,
|
|||
if (compression_header_size != 0)
|
||||
{
|
||||
if (!bfd_check_compression_header (abfd, header, sec,
|
||||
uncompressed_size_p))
|
||||
uncompressed_size_p,
|
||||
uncompressed_align_pow_p))
|
||||
compression_header_size = -1;
|
||||
}
|
||||
/* Check for the pathalogical case of a debug string section that
|
||||
|
@ -449,9 +459,11 @@ bfd_is_section_compressed (bfd *abfd, sec_ptr sec)
|
|||
{
|
||||
int compression_header_size;
|
||||
bfd_size_type uncompressed_size;
|
||||
unsigned int uncompressed_align_power;
|
||||
return (bfd_is_section_compressed_with_header (abfd, sec,
|
||||
&compression_header_size,
|
||||
&uncompressed_size)
|
||||
&uncompressed_size,
|
||||
&uncompressed_align_power)
|
||||
&& compression_header_size >= 0
|
||||
&& uncompressed_size > 0);
|
||||
}
|
||||
|
@ -480,6 +492,7 @@ bfd_init_section_decompress_status (bfd *abfd, sec_ptr sec)
|
|||
int compression_header_size;
|
||||
int header_size;
|
||||
bfd_size_type uncompressed_size;
|
||||
unsigned int uncompressed_alignment_power = 0;
|
||||
|
||||
compression_header_size = bfd_get_compression_header_size (abfd, sec);
|
||||
if (compression_header_size > MAX_COMPRESSION_HEADER_SIZE)
|
||||
|
@ -508,7 +521,8 @@ bfd_init_section_decompress_status (bfd *abfd, sec_ptr sec)
|
|||
uncompressed_size = bfd_getb64 (header + 4);
|
||||
}
|
||||
else if (!bfd_check_compression_header (abfd, header, sec,
|
||||
&uncompressed_size))
|
||||
&uncompressed_size,
|
||||
&uncompressed_alignment_power))
|
||||
{
|
||||
bfd_set_error (bfd_error_wrong_format);
|
||||
return FALSE;
|
||||
|
@ -516,6 +530,7 @@ bfd_init_section_decompress_status (bfd *abfd, sec_ptr sec)
|
|||
|
||||
sec->compressed_size = sec->size;
|
||||
sec->size = uncompressed_size;
|
||||
bfd_set_section_alignment (abfd, sec, uncompressed_alignment_power);
|
||||
sec->compress_status = DECOMPRESS_SECTION_SIZED;
|
||||
|
||||
return TRUE;
|
||||
|
|
|
@ -1177,11 +1177,12 @@ _bfd_elf_make_section_from_shdr (bfd *abfd,
|
|||
enum { nothing, compress, decompress } action = nothing;
|
||||
int compression_header_size;
|
||||
bfd_size_type uncompressed_size;
|
||||
unsigned int uncompressed_align_power;
|
||||
bfd_boolean compressed
|
||||
= bfd_is_section_compressed_with_header (abfd, newsect,
|
||||
&compression_header_size,
|
||||
&uncompressed_size);
|
||||
|
||||
&uncompressed_size,
|
||||
&uncompressed_align_power);
|
||||
if (compressed)
|
||||
{
|
||||
/* Compressed section. Check if we should decompress. */
|
||||
|
|
|
@ -1,3 +1,12 @@
|
|||
2018-11-27 Mark Wielaard <mark@klomp.org>
|
||||
|
||||
PR binutils/23919
|
||||
* 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.
|
||||
|
||||
2018-11-20 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
PR binutils/23898
|
||||
|
|
|
@ -13397,12 +13397,6 @@ dump_section_as_strings (Elf_Internal_Shdr * section, Filedata * filedata)
|
|||
printable_section_name (filedata, section), chdr.ch_type);
|
||||
return FALSE;
|
||||
}
|
||||
else if (chdr.ch_addralign != section->sh_addralign)
|
||||
{
|
||||
warn (_("compressed section '%s' is corrupted\n"),
|
||||
printable_section_name (filedata, section));
|
||||
return FALSE;
|
||||
}
|
||||
uncompressed_size = chdr.ch_size;
|
||||
start += compression_header_size;
|
||||
new_size -= compression_header_size;
|
||||
|
@ -13544,12 +13538,6 @@ dump_section_as_bytes (Elf_Internal_Shdr * section,
|
|||
printable_section_name (filedata, section), chdr.ch_type);
|
||||
return FALSE;
|
||||
}
|
||||
else if (chdr.ch_addralign != section->sh_addralign)
|
||||
{
|
||||
warn (_("compressed section '%s' is corrupted\n"),
|
||||
printable_section_name (filedata, section));
|
||||
return FALSE;
|
||||
}
|
||||
uncompressed_size = chdr.ch_size;
|
||||
start += compression_header_size;
|
||||
new_size -= compression_header_size;
|
||||
|
@ -13719,12 +13707,6 @@ load_specific_debug_section (enum dwarf_section_display_enum debug,
|
|||
section->name, chdr.ch_type);
|
||||
return FALSE;
|
||||
}
|
||||
else if (chdr.ch_addralign != sec->sh_addralign)
|
||||
{
|
||||
warn (_("compressed section '%s' is corrupted\n"),
|
||||
section->name);
|
||||
return FALSE;
|
||||
}
|
||||
uncompressed_size = chdr.ch_size;
|
||||
start += compression_header_size;
|
||||
size -= compression_header_size;
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
#...
|
||||
+\[[ 0-9]+\] .debug_info +(PROGBITS|MIPS_DWARF) +0+ +[0-9a-f]+ +[0-9a-f]+ [0-9a-f]+ +C +0 +0 +1
|
||||
+\[[ 0-9]+\] .debug_info +(PROGBITS|MIPS_DWARF) +0+ +[0-9a-f]+ +[0-9a-f]+ [0-9a-f]+ +C +0 +0 +(4|8)
|
||||
#pass
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#...
|
||||
+\[[ 0-9]+\] .debug_info
|
||||
+(PROGBITS|MIPS_DWARF) +0+ +[0-9a-f]+ +[0-9a-f]+ +[0-9a-f]+ +0 +0 +1
|
||||
+(PROGBITS|MIPS_DWARF) +0+ +[0-9a-f]+ +[0-9a-f]+ +[0-9a-f]+ +0 +0 +(4|8)
|
||||
+\[0+800\]: COMPRESSED
|
||||
+ZLIB, 0+9d, 1
|
||||
#pass
|
||||
|
|
Loading…
Reference in New Issue