aboutsummaryrefslogtreecommitdiff
path: root/bfd
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2019-02-18 15:08:57 +0000
committerNick Clifton <nickc@redhat.com>2019-02-18 15:08:57 +0000
commit88739f776b733b0b84600b283417f862a010bb5d (patch)
tree6da6a1752da4d524d55c8f0f982ef047bd1a0a75 /bfd
parent292144de4f26e2c6a1fa9d84da2c7758872d4725 (diff)
downloadfsf-binutils-gdb-88739f776b733b0b84600b283417f862a010bb5d.zip
fsf-binutils-gdb-88739f776b733b0b84600b283417f862a010bb5d.tar.gz
fsf-binutils-gdb-88739f776b733b0b84600b283417f862a010bb5d.tar.bz2
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. 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. gold * merge.cc (Output_merge_string<Char_type>::do_add_input_section): Get addralign from decompressed_section_contents. * object.cc (build_compressed_section_map): Set info.addralign. (Object::decompressed_section_contents): Add a palign argument and store p->second.addralign in *palign if it isn't NULL. * object.h (Compressed_section_info): Add addralign. (section_is_compressed): Add a palign argument, default it to NULL, store p->second.addralign in *palign if it isn't NULL. (Object::decompressed_section_contents): Likewise. * output.cc (Output_section::add_input_section): Get addralign from section_is_compressed.
Diffstat (limited to 'bfd')
-rw-r--r--bfd/ChangeLog28
-rw-r--r--bfd/bfd-in2.h6
-rw-r--r--bfd/bfd.c21
-rw-r--r--bfd/compress.c37
-rw-r--r--bfd/elf.c4
5 files changed, 78 insertions, 18 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index e144a6f..4582b8c 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.
+
2019-02-10 H.J. Lu <hongjiu.lu@intel.com>
PR ld/24151
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index f53dbb5..d0c2190 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -7279,7 +7279,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);
@@ -7855,7 +7856,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 828241d..dfeedf9 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)
{