summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Wielaard <mark@klomp.org>2018-11-24 23:11:35 +0100
committerMark Wielaard <mark@klomp.org>2018-11-24 23:11:35 +0100
commitc78cd782e55af31757eb7446612d9e96c800387f (patch)
treeec7896363e2178bad579b5540728bbed738712e3
parentRe-fix leak in source.c (open_source_file). (diff)
downloadbinutils-gdb-compress-align.tar.gz
binutils-gdb-compress-align.tar.bz2
binutils-gdb-compress-align.tar.xz
PR 23919 - bfd doesn't handle ELF compressed data alignment.compress-align
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. bfd_check_compression_header and bfd_is_section_compressed_with_header now return both the uncompressed size and alignment of the uncompressed data. Two testcases were adjusted to check for the correct alignment.
-rw-r--r--bfd/ChangeLog19
-rw-r--r--bfd/bfd-in2.h6
-rw-r--r--bfd/bfd.c20
-rw-r--r--bfd/compress.c35
-rw-r--r--bfd/elf.c5
-rw-r--r--binutils/ChangeLog9
-rw-r--r--binutils/readelf.c18
-rw-r--r--binutils/testsuite/binutils-all/dw2-3.rS2
-rw-r--r--binutils/testsuite/binutils-all/dw2-3.rt2
9 files changed, 77 insertions, 39 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 35f0706..1901aa0 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,22 @@
12018-11-24 Mark Wielaard <mark@klomp.org>
2
3 PR binutils/23919
4 * bfd.c (bfd_update_compression_header): Explicitly set alignment.
5 (bfd_check_compression_header): Add uncompressed_alignment_power
6 argument. Check ch_addralign is a power of 2.
7 * bfd-in2.h: Regenerated.
8 * compress.c (bfd_compress_section_contents): Get and set
9 orig_uncompressed_alignment_pow if section is decompressed.
10 (bfd_is_section_compressed_with_header): Add and get
11 uncompressed_align_pow_p argument.
12 (bfd_is_section_compressed): Add uncompressed_align_power argument
13 to bfd_is_section_compressed_with_header call.
14 (bfd_init_section_decompress_status): Get and set
15 uncompressed_alignment_power.
16 * elf.c (_bfd_elf_make_section_from_shdr): Add
17 uncompressed_align_power argument to
18 bfd_is_section_compressed_with_header call.
19
12018-11-21 Jozef Lawrynowicz <jozef.l@mittosystems.com> 202018-11-21 Jozef Lawrynowicz <jozef.l@mittosystems.com>
2 21
3 * elf32-msp430.c (elf32_msp430_merge_mspabi_attributes): Do not 22 * elf32-msp430.c (elf32_msp430_merge_mspabi_attributes): Do not
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index ee8cd7e..6d92c51 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -7419,7 +7419,8 @@ void bfd_update_compression_header
7419 7419
7420bfd_boolean bfd_check_compression_header 7420bfd_boolean bfd_check_compression_header
7421 (bfd *abfd, bfd_byte *contents, asection *sec, 7421 (bfd *abfd, bfd_byte *contents, asection *sec,
7422 bfd_size_type *uncompressed_size); 7422 bfd_size_type *uncompressed_size,
7423 unsigned int *uncompressed_alignment_power);
7423 7424
7424int bfd_get_compression_header_size (bfd *abfd, asection *sec); 7425int bfd_get_compression_header_size (bfd *abfd, asection *sec);
7425 7426
@@ -8006,7 +8007,8 @@ void bfd_cache_section_contents
8006bfd_boolean bfd_is_section_compressed_with_header 8007bfd_boolean bfd_is_section_compressed_with_header
8007 (bfd *abfd, asection *section, 8008 (bfd *abfd, asection *section,
8008 int *compression_header_size_p, 8009 int *compression_header_size_p,
8009 bfd_size_type *uncompressed_size_p); 8010 bfd_size_type *uncompressed_size_p,
8011 unsigned int *uncompressed_alignment_power_p);
8010 8012
8011bfd_boolean bfd_is_section_compressed 8013bfd_boolean bfd_is_section_compressed
8012 (bfd *abfd, asection *section); 8014 (bfd *abfd, asection *section);
diff --git a/bfd/bfd.c b/bfd/bfd.c
index 15becd7..2b65829 100644
--- a/bfd/bfd.c
+++ b/bfd/bfd.c
@@ -2332,6 +2332,8 @@ bfd_update_compression_header (bfd *abfd, bfd_byte *contents,
2332 bfd_put_32 (abfd, sec->size, &echdr->ch_size); 2332 bfd_put_32 (abfd, sec->size, &echdr->ch_size);
2333 bfd_put_32 (abfd, 1 << sec->alignment_power, 2333 bfd_put_32 (abfd, 1 << sec->alignment_power,
2334 &echdr->ch_addralign); 2334 &echdr->ch_addralign);
2335 /* bfd_log2 (alignof (Elf32_Chdr)) */
2336 bfd_set_section_alignment (abfd, sec, 2);
2335 } 2337 }
2336 else 2338 else
2337 { 2339 {
@@ -2342,6 +2344,8 @@ bfd_update_compression_header (bfd *abfd, bfd_byte *contents,
2342 bfd_put_64 (abfd, sec->size, &echdr->ch_size); 2344 bfd_put_64 (abfd, sec->size, &echdr->ch_size);
2343 bfd_put_64 (abfd, 1 << sec->alignment_power, 2345 bfd_put_64 (abfd, 1 << sec->alignment_power,
2344 &echdr->ch_addralign); 2346 &echdr->ch_addralign);
2347 /* bfd_log2 (alignof (Elf64_Chdr)) */
2348 bfd_set_section_alignment (abfd, sec, 3);
2345 } 2349 }
2346 } 2350 }
2347 else 2351 else
@@ -2354,6 +2358,8 @@ bfd_update_compression_header (bfd *abfd, bfd_byte *contents,
2354 order. */ 2358 order. */
2355 memcpy (contents, "ZLIB", 4); 2359 memcpy (contents, "ZLIB", 4);
2356 bfd_putb64 (sec->size, contents + 4); 2360 bfd_putb64 (sec->size, contents + 4);
2361 /* No way to keep the original alignment, just use 1 always. */
2362 bfd_set_section_alignment (abfd, sec, 0);
2357 } 2363 }
2358 } 2364 }
2359 } 2365 }
@@ -2368,12 +2374,14 @@ bfd_update_compression_header (bfd *abfd, bfd_byte *contents,
2368 SYNOPSIS 2374 SYNOPSIS
2369 bfd_boolean bfd_check_compression_header 2375 bfd_boolean bfd_check_compression_header
2370 (bfd *abfd, bfd_byte *contents, asection *sec, 2376 (bfd *abfd, bfd_byte *contents, asection *sec,
2371 bfd_size_type *uncompressed_size); 2377 bfd_size_type *uncompressed_size,
2378 unsigned int *uncompressed_alignment_power);
2372 2379
2373DESCRIPTION 2380DESCRIPTION
2374 Check the compression header at CONTENTS of SEC in ABFD and 2381 Check the compression header at CONTENTS of SEC in ABFD and
2375 store the uncompressed size in UNCOMPRESSED_SIZE if the 2382 store the uncompressed size in UNCOMPRESSED_SIZE and the
2376 compression header is valid. 2383 uncompressed data alignment in UNCOMPRESSED_ALIGNMENT_POWER
2384 if the compression header is valid.
2377 2385
2378RETURNS 2386RETURNS
2379 Return TRUE if the compression header is valid. 2387 Return TRUE if the compression header is valid.
@@ -2382,7 +2390,8 @@ RETURNS
2382bfd_boolean 2390bfd_boolean
2383bfd_check_compression_header (bfd *abfd, bfd_byte *contents, 2391bfd_check_compression_header (bfd *abfd, bfd_byte *contents,
2384 asection *sec, 2392 asection *sec,
2385 bfd_size_type *uncompressed_size) 2393 bfd_size_type *uncompressed_size,
2394 unsigned int *uncompressed_alignment_power)
2386{ 2395{
2387 if (bfd_get_flavour (abfd) == bfd_target_elf_flavour 2396 if (bfd_get_flavour (abfd) == bfd_target_elf_flavour
2388 && (elf_section_flags (sec) & SHF_COMPRESSED) != 0) 2397 && (elf_section_flags (sec) & SHF_COMPRESSED) != 0)
@@ -2404,9 +2413,10 @@ bfd_check_compression_header (bfd *abfd, bfd_byte *contents,
2404 chdr.ch_addralign = bfd_get_64 (abfd, &echdr->ch_addralign); 2413 chdr.ch_addralign = bfd_get_64 (abfd, &echdr->ch_addralign);
2405 } 2414 }
2406 if (chdr.ch_type == ELFCOMPRESS_ZLIB 2415 if (chdr.ch_type == ELFCOMPRESS_ZLIB
2407 && chdr.ch_addralign == 1U << sec->alignment_power) 2416 && chdr.ch_addralign == (1U << bfd_log2 (chdr.ch_addralign)))
2408 { 2417 {
2409 *uncompressed_size = chdr.ch_size; 2418 *uncompressed_size = chdr.ch_size;
2419 *uncompressed_alignment_power = bfd_log2 (chdr.ch_addralign);
2410 return TRUE; 2420 return TRUE;
2411 } 2421 }
2412 } 2422 }
diff --git a/bfd/compress.c b/bfd/compress.c
index 53e566e..97ea624 100644
--- a/bfd/compress.c
+++ b/bfd/compress.c
@@ -84,11 +84,13 @@ bfd_compress_section_contents (bfd *abfd, sec_ptr sec,
84 int zlib_size = 0; 84 int zlib_size = 0;
85 int orig_compression_header_size; 85 int orig_compression_header_size;
86 bfd_size_type orig_uncompressed_size; 86 bfd_size_type orig_uncompressed_size;
87 unsigned int orig_uncompressed_alignment_pow;
87 int header_size = bfd_get_compression_header_size (abfd, NULL); 88 int header_size = bfd_get_compression_header_size (abfd, NULL);
88 bfd_boolean compressed 89 bfd_boolean compressed
89 = bfd_is_section_compressed_with_header (abfd, sec, 90 = bfd_is_section_compressed_with_header (abfd, sec,
90 &orig_compression_header_size, 91 &orig_compression_header_size,
91 &orig_uncompressed_size); 92 &orig_uncompressed_size,
93 &orig_uncompressed_alignment_pow);
92 94
93 /* Either ELF compression header or the 12-byte, "ZLIB" + 8-byte size, 95 /* Either ELF compression header or the 12-byte, "ZLIB" + 8-byte size,
94 overhead in .zdebug* section. */ 96 overhead in .zdebug* section. */
@@ -153,6 +155,9 @@ bfd_compress_section_contents (bfd *abfd, sec_ptr sec,
153 return 0; 155 return 0;
154 } 156 }
155 free (uncompressed_buffer); 157 free (uncompressed_buffer);
158 bfd_set_section_alignment (abfd, sec,
159 orig_uncompressed_alignment_pow);
160
156 sec->contents = buffer; 161 sec->contents = buffer;
157 sec->compress_status = COMPRESS_SECTION_DONE; 162 sec->compress_status = COMPRESS_SECTION_DONE;
158 return orig_uncompressed_size; 163 return orig_uncompressed_size;
@@ -364,20 +369,24 @@ SYNOPSIS
364 bfd_boolean bfd_is_section_compressed_with_header 369 bfd_boolean bfd_is_section_compressed_with_header
365 (bfd *abfd, asection *section, 370 (bfd *abfd, asection *section,
366 int *compression_header_size_p, 371 int *compression_header_size_p,
367 bfd_size_type *uncompressed_size_p); 372 bfd_size_type *uncompressed_size_p,
373 unsigned int *uncompressed_alignment_power_p);
368 374
369DESCRIPTION 375DESCRIPTION
370 Return @code{TRUE} if @var{section} is compressed. Compression 376 Return @code{TRUE} if @var{section} is compressed. Compression
371 header size is returned in @var{compression_header_size_p} and 377 header size is returned in @var{compression_header_size_p},
372 uncompressed size is returned in @var{uncompressed_size_p}. If 378 uncompressed size is returned in @var{uncompressed_size_p}
373 compression is unsupported, compression header size is returned 379 and the uncompressed data alignement power is returned in
374 with -1 and uncompressed size is returned with 0. 380 @var{uncompressed_align_pow_p}. If compression is
381 unsupported, compression header size is returned with -1
382 and uncompressed size is returned with 0.
375*/ 383*/
376 384
377bfd_boolean 385bfd_boolean
378bfd_is_section_compressed_with_header (bfd *abfd, sec_ptr sec, 386bfd_is_section_compressed_with_header (bfd *abfd, sec_ptr sec,
379 int *compression_header_size_p, 387 int *compression_header_size_p,
380 bfd_size_type *uncompressed_size_p) 388 bfd_size_type *uncompressed_size_p,
389 unsigned int *uncompressed_align_pow_p)
381{ 390{
382 bfd_byte header[MAX_COMPRESSION_HEADER_SIZE]; 391 bfd_byte header[MAX_COMPRESSION_HEADER_SIZE];
383 int compression_header_size; 392 int compression_header_size;
@@ -412,7 +421,8 @@ bfd_is_section_compressed_with_header (bfd *abfd, sec_ptr sec,
412 if (compression_header_size != 0) 421 if (compression_header_size != 0)
413 { 422 {
414 if (!bfd_check_compression_header (abfd, header, sec, 423 if (!bfd_check_compression_header (abfd, header, sec,
415 uncompressed_size_p)) 424 uncompressed_size_p,
425 uncompressed_align_pow_p))
416 compression_header_size = -1; 426 compression_header_size = -1;
417 } 427 }
418 /* Check for the pathalogical case of a debug string section that 428 /* Check for the pathalogical case of a debug string section that
@@ -449,9 +459,11 @@ bfd_is_section_compressed (bfd *abfd, sec_ptr sec)
449{ 459{
450 int compression_header_size; 460 int compression_header_size;
451 bfd_size_type uncompressed_size; 461 bfd_size_type uncompressed_size;
462 unsigned int uncompressed_align_power;
452 return (bfd_is_section_compressed_with_header (abfd, sec, 463 return (bfd_is_section_compressed_with_header (abfd, sec,
453 &compression_header_size, 464 &compression_header_size,
454 &uncompressed_size) 465 &uncompressed_size,
466 &uncompressed_align_power)
455 && compression_header_size >= 0 467 && compression_header_size >= 0
456 && uncompressed_size > 0); 468 && uncompressed_size > 0);
457} 469}
@@ -480,6 +492,7 @@ bfd_init_section_decompress_status (bfd *abfd, sec_ptr sec)
480 int compression_header_size; 492 int compression_header_size;
481 int header_size; 493 int header_size;
482 bfd_size_type uncompressed_size; 494 bfd_size_type uncompressed_size;
495 unsigned int uncompressed_alignment_power = 0;
483 496
484 compression_header_size = bfd_get_compression_header_size (abfd, sec); 497 compression_header_size = bfd_get_compression_header_size (abfd, sec);
485 if (compression_header_size > MAX_COMPRESSION_HEADER_SIZE) 498 if (compression_header_size > MAX_COMPRESSION_HEADER_SIZE)
@@ -508,7 +521,8 @@ bfd_init_section_decompress_status (bfd *abfd, sec_ptr sec)
508 uncompressed_size = bfd_getb64 (header + 4); 521 uncompressed_size = bfd_getb64 (header + 4);
509 } 522 }
510 else if (!bfd_check_compression_header (abfd, header, sec, 523 else if (!bfd_check_compression_header (abfd, header, sec,
511 &uncompressed_size)) 524 &uncompressed_size,
525 &uncompressed_alignment_power))
512 { 526 {
513 bfd_set_error (bfd_error_wrong_format); 527 bfd_set_error (bfd_error_wrong_format);
514 return FALSE; 528 return FALSE;
@@ -516,6 +530,7 @@ bfd_init_section_decompress_status (bfd *abfd, sec_ptr sec)
516 530
517 sec->compressed_size = sec->size; 531 sec->compressed_size = sec->size;
518 sec->size = uncompressed_size; 532 sec->size = uncompressed_size;
533 bfd_set_section_alignment (abfd, sec, uncompressed_alignment_power);
519 sec->compress_status = DECOMPRESS_SECTION_SIZED; 534 sec->compress_status = DECOMPRESS_SECTION_SIZED;
520 535
521 return TRUE; 536 return TRUE;
diff --git a/bfd/elf.c b/bfd/elf.c
index bebda20..604971d 100644
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -1177,11 +1177,12 @@ _bfd_elf_make_section_from_shdr (bfd *abfd,
1177 enum { nothing, compress, decompress } action = nothing; 1177 enum { nothing, compress, decompress } action = nothing;
1178 int compression_header_size; 1178 int compression_header_size;
1179 bfd_size_type uncompressed_size; 1179 bfd_size_type uncompressed_size;
1180 unsigned int uncompressed_align_power;
1180 bfd_boolean compressed 1181 bfd_boolean compressed
1181 = bfd_is_section_compressed_with_header (abfd, newsect, 1182 = bfd_is_section_compressed_with_header (abfd, newsect,
1182 &compression_header_size, 1183 &compression_header_size,
1183 &uncompressed_size); 1184 &uncompressed_size,
1184 1185 &uncompressed_align_power);
1185 if (compressed) 1186 if (compressed)
1186 { 1187 {
1187 /* Compressed section. Check if we should decompress. */ 1188 /* Compressed section. Check if we should decompress. */
diff --git a/binutils/ChangeLog b/binutils/ChangeLog
index ed80459..928b937 100644
--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -1,3 +1,12 @@
12018-11-24 Mark Wielaard <mark@klomp.org>
2
3 PR binutils/23919
4 * readelf.c (dump_sections_as_strings): Remove bogus addralign check.
5 (dump_sections_as_bytes): Likewise.
6 (load_specific_debug_sections): Likewise.
7 * testsuite/binutils-all/dw2-3.rS: Adjust alignment.
8 * testsuite/binutils-all/dw2-3.rt: Likewise.
9
12018-11-20 H.J. Lu <hongjiu.lu@intel.com> 102018-11-20 H.J. Lu <hongjiu.lu@intel.com>
2 11
3 PR binutils/23898 12 PR binutils/23898
diff --git a/binutils/readelf.c b/binutils/readelf.c
index 3974400..afb039f 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -13397,12 +13397,6 @@ dump_section_as_strings (Elf_Internal_Shdr * section, Filedata * filedata)
13397 printable_section_name (filedata, section), chdr.ch_type); 13397 printable_section_name (filedata, section), chdr.ch_type);
13398 return FALSE; 13398 return FALSE;
13399 } 13399 }
13400 else if (chdr.ch_addralign != section->sh_addralign)
13401 {
13402 warn (_("compressed section '%s' is corrupted\n"),
13403 printable_section_name (filedata, section));
13404 return FALSE;
13405 }
13406 uncompressed_size = chdr.ch_size; 13400 uncompressed_size = chdr.ch_size;
13407 start += compression_header_size; 13401 start += compression_header_size;
13408 new_size -= compression_header_size; 13402 new_size -= compression_header_size;
@@ -13544,12 +13538,6 @@ dump_section_as_bytes (Elf_Internal_Shdr * section,
13544 printable_section_name (filedata, section), chdr.ch_type); 13538 printable_section_name (filedata, section), chdr.ch_type);
13545 return FALSE; 13539 return FALSE;
13546 } 13540 }
13547 else if (chdr.ch_addralign != section->sh_addralign)
13548 {
13549 warn (_("compressed section '%s' is corrupted\n"),
13550 printable_section_name (filedata, section));
13551 return FALSE;
13552 }
13553 uncompressed_size = chdr.ch_size; 13541 uncompressed_size = chdr.ch_size;
13554 start += compression_header_size; 13542 start += compression_header_size;
13555 new_size -= compression_header_size; 13543 new_size -= compression_header_size;
@@ -13719,12 +13707,6 @@ load_specific_debug_section (enum dwarf_section_display_enum debug,
13719 section->name, chdr.ch_type); 13707 section->name, chdr.ch_type);
13720 return FALSE; 13708 return FALSE;
13721 } 13709 }
13722 else if (chdr.ch_addralign != sec->sh_addralign)
13723 {
13724 warn (_("compressed section '%s' is corrupted\n"),
13725 section->name);
13726 return FALSE;
13727 }
13728 uncompressed_size = chdr.ch_size; 13710 uncompressed_size = chdr.ch_size;
13729 start += compression_header_size; 13711 start += compression_header_size;
13730 size -= compression_header_size; 13712 size -= compression_header_size;
diff --git a/binutils/testsuite/binutils-all/dw2-3.rS b/binutils/testsuite/binutils-all/dw2-3.rS
index f1637e9..86bc73d 100644
--- a/binutils/testsuite/binutils-all/dw2-3.rS
+++ b/binutils/testsuite/binutils-all/dw2-3.rS
@@ -1,3 +1,3 @@
1#... 1#...
2 +\[[ 0-9]+\] .debug_info +(PROGBITS|MIPS_DWARF) +0+ +[0-9a-f]+ +[0-9a-f]+ [0-9a-f]+ +C +0 +0 +1 2 +\[[ 0-9]+\] .debug_info +(PROGBITS|MIPS_DWARF) +0+ +[0-9a-f]+ +[0-9a-f]+ [0-9a-f]+ +C +0 +0 +(4|8)
3#pass 3#pass
diff --git a/binutils/testsuite/binutils-all/dw2-3.rt b/binutils/testsuite/binutils-all/dw2-3.rt
index f59cbaa..74e7f8d 100644
--- a/binutils/testsuite/binutils-all/dw2-3.rt
+++ b/binutils/testsuite/binutils-all/dw2-3.rt
@@ -1,6 +1,6 @@
1#... 1#...
2 +\[[ 0-9]+\] .debug_info 2 +\[[ 0-9]+\] .debug_info
3 +(PROGBITS|MIPS_DWARF) +0+ +[0-9a-f]+ +[0-9a-f]+ +[0-9a-f]+ +0 +0 +1 3 +(PROGBITS|MIPS_DWARF) +0+ +[0-9a-f]+ +[0-9a-f]+ +[0-9a-f]+ +0 +0 +(4|8)
4 +\[0+800\]: COMPRESSED 4 +\[0+800\]: COMPRESSED
5 +ZLIB, 0+9d, 1 5 +ZLIB, 0+9d, 1
6#pass 6#pass