303 lines
11 KiB
Diff
303 lines
11 KiB
Diff
From 6d33d996167a33552b68c036f1b1571a208ace42 Mon Sep 17 00:00:00 2001
|
|
From: Nick Clifton <nickc@redhat.com>
|
|
Date: Tue, 26 Feb 2019 19:57:46 +0000
|
|
Subject: [PATCH 1/1] Import patch to fix PR23919 from the mainline.
|
|
|
|
PR binutils/23919
|
|
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.
|
|
|
|
* compress.c (bfd_is_section_compressed_with_header): Initialize
|
|
* uncompressed_align_pow_p to 0.
|
|
---
|
|
bfd/ChangeLog | 28 ++++++++++++++++++++++++
|
|
bfd/bfd-in2.h | 6 ++++--
|
|
bfd/bfd.c | 21 +++++++++++++-----
|
|
bfd/compress.c | 37 +++++++++++++++++++++++---------
|
|
bfd/elf.c | 4 +++-
|
|
14 files changed, 138 insertions(+), 50 deletions(-)
|
|
|
|
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
|
|
index 5bb453e..2dc2d97 100644
|
|
--- a/bfd/ChangeLog
|
|
+++ b/bfd/ChangeLog
|
|
@@ -1,3 +1,31 @@
|
|
+2019-02-18 Nick Clifton <nickc@redhat.com>
|
|
+
|
|
+ Import from the mainline:
|
|
+ 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-27 H.J. Lu <hongjiu.lu@intel.com>
|
|
+
|
|
+ PR binutils/23919
|
|
+ * compress.c (bfd_is_section_compressed_with_header): Initialize
|
|
+ * uncompressed_align_pow_p to 0.
|
|
+
|
|
2018-07-04 Joel Brobecker <brobecker@adacore.com>
|
|
|
|
* development.sh (development): Set to false.
|
|
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
|
|
index 93745bd..d2944a0 100644
|
|
--- a/bfd/bfd-in2.h
|
|
+++ b/bfd/bfd-in2.h
|
|
@@ -7292,7 +7292,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);
|
|
|
|
@@ -7868,7 +7869,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);
|
|
diff --git a/bfd/bfd.c b/bfd/bfd.c
|
|
index 8517104..b859d65 100644
|
|
--- a/bfd/bfd.c
|
|
+++ b/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,15 @@ 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 +2391,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 +2414,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;
|
|
}
|
|
}
|
|
diff --git a/bfd/compress.c b/bfd/compress.c
|
|
index 53e566e..38803eb 100644
|
|
--- a/bfd/compress.c
|
|
+++ b/bfd/compress.c
|
|
@@ -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,8 @@ 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 +368,25 @@ 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;
|
|
@@ -385,6 +394,8 @@ bfd_is_section_compressed_with_header (bfd *abfd, sec_ptr sec,
|
|
unsigned int saved = sec->compress_status;
|
|
bfd_boolean compressed;
|
|
|
|
+ *uncompressed_align_pow_p = 0;
|
|
+
|
|
compression_header_size = bfd_get_compression_header_size (abfd, sec);
|
|
if (compression_header_size > MAX_COMPRESSION_HEADER_SIZE)
|
|
abort ();
|
|
@@ -412,7 +423,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 +461,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 +494,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 +523,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 +532,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;
|
|
diff --git a/bfd/elf.c b/bfd/elf.c
|
|
index 0f75375..88a5d12 100644
|
|
--- a/bfd/elf.c
|
|
+++ b/bfd/elf.c
|
|
@@ -1177,10 +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)
|
|
{
|
|
|
|
|