aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2022-10-14 21:59:23 +1030
committerAlan Modra <amodra@gmail.com>2022-10-16 13:54:50 +1030
commit206e9791cb09459bf92603428370c16bfde282ac (patch)
tree697bb43e78ec7616c659a870e3f21043b3d1e5a7
parent4f722d4a721aaee24323138fc3b564ad1545af93 (diff)
downloadgdb-206e9791cb09459bf92603428370c16bfde282ac.zip
gdb-206e9791cb09459bf92603428370c16bfde282ac.tar.gz
gdb-206e9791cb09459bf92603428370c16bfde282ac.tar.bz2
zlib-gabi to zstd woes
So we had a zlib-gabi .debug_info section that increased in size with zstd, so much so that it was better to leave the section uncompressed. Things went horribly wrong when the section was read again later. The section was read again off disk using the uncompressed size. So you get the zlib section again with some garbage at the end. Fix that particular problem by setting the section flag SEC_IN_MEMORY. Any future read will get sec->contents. Also, if the section is to be left uncompressed, the input SHF_COMPRESSED flag needs to be reset otherwise objcopy will copy it to output. Finally, bfd_convert_section_contents needed a small update to handle zstd compressed sections, and I've deleted bfd_cache_section_contents. * bfd.c (bfd_convert_section_contents): Handle zstd. * compress.c (bfd_compress_section_contents): When section contents are uncompressed set SEC_IN_MEMORY flag, compress_status to COMRESS_SECTION_NONE, and clear SHF_COMPRESSED. Set SEC_IN_MEMORY for compressed contents. (bfd_get_full_section_contents): Don't check section size against file size when SEC_IN_MEMORY. (bfd_cache_section_contents): Delete function. * elf32-arm.c (elf32_arm_get_synthetic_symtab): Expand bfd_cache_section_contents here. * bfd-in2.h: Regenerate.
-rw-r--r--bfd/bfd-in2.h3
-rw-r--r--bfd/bfd.c4
-rw-r--r--bfd/compress.c29
-rw-r--r--bfd/elf32-arm.c6
4 files changed, 11 insertions, 31 deletions
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index 25e1806..534a464 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -7964,9 +7964,6 @@ bfd_byte *bfd_simple_get_relocated_section_contents
bool bfd_get_full_section_contents
(bfd *abfd, asection *section, bfd_byte **ptr);
-void bfd_cache_section_contents
- (asection *sec, void *contents);
-
bool bfd_is_section_compressed_info
(bfd *abfd, asection *section,
int *compression_header_size_p,
diff --git a/bfd/bfd.c b/bfd/bfd.c
index 5f2033b..4fca825 100644
--- a/bfd/bfd.c
+++ b/bfd/bfd.c
@@ -2801,14 +2801,14 @@ bfd_convert_section_contents (bfd *ibfd, sec_ptr isec, bfd *obfd,
if (ohdr_size == sizeof (Elf32_External_Chdr))
{
Elf32_External_Chdr *echdr = (Elf32_External_Chdr *) contents;
- bfd_put_32 (obfd, ELFCOMPRESS_ZLIB, &echdr->ch_type);
+ bfd_put_32 (obfd, chdr.ch_type, &echdr->ch_type);
bfd_put_32 (obfd, chdr.ch_size, &echdr->ch_size);
bfd_put_32 (obfd, chdr.ch_addralign, &echdr->ch_addralign);
}
else
{
Elf64_External_Chdr *echdr = (Elf64_External_Chdr *) contents;
- bfd_put_32 (obfd, ELFCOMPRESS_ZLIB, &echdr->ch_type);
+ bfd_put_32 (obfd, chdr.ch_type, &echdr->ch_type);
bfd_put_32 (obfd, 0, &echdr->ch_reserved);
bfd_put_64 (obfd, chdr.ch_size, &echdr->ch_size);
bfd_put_64 (obfd, chdr.ch_addralign, &echdr->ch_addralign);
diff --git a/bfd/compress.c b/bfd/compress.c
index 364df14..9608a0a 100644
--- a/bfd/compress.c
+++ b/bfd/compress.c
@@ -151,7 +151,8 @@ bfd_compress_section_contents (bfd *abfd, sec_ptr sec)
free (input_buffer);
bfd_set_section_alignment (sec, uncompressed_alignment_pow);
sec->contents = buffer;
- sec->compress_status = COMPRESS_SECTION_DONE;
+ sec->flags |= SEC_IN_MEMORY;
+ sec->compress_status = COMPRESS_SECTION_NONE;
sec->size = uncompressed_size;
input_buffer = buffer;
}
@@ -206,6 +207,7 @@ bfd_compress_section_contents (bfd *abfd, sec_ptr sec)
if (compressed_size >= uncompressed_size)
{
memcpy (buffer, input_buffer, uncompressed_size);
+ elf_section_flags (sec) &= ~SHF_COMPRESSED;
sec->compress_status = COMPRESS_SECTION_NONE;
}
else
@@ -216,6 +218,7 @@ bfd_compress_section_contents (bfd *abfd, sec_ptr sec)
sec->compress_status = COMPRESS_SECTION_DONE;
}
sec->contents = buffer;
+ sec->flags |= SEC_IN_MEMORY;
free (input_buffer);
return uncompressed_size;
}
@@ -268,6 +271,7 @@ bfd_get_full_section_contents (bfd *abfd, sec_ptr sec, bfd_byte **ptr)
ufile_ptr filesize = bfd_get_file_size (abfd);
if (filesize > 0
&& filesize < sz
+ && (bfd_section_flags (sec) & SEC_IN_MEMORY) == 0
/* PR 24753: Linker created sections can be larger than
the file size, eg if they are being used to hold stubs. */
&& (bfd_section_flags (sec) & SEC_LINKER_CREATED) == 0
@@ -382,29 +386,6 @@ bfd_get_full_section_contents (bfd *abfd, sec_ptr sec, bfd_byte **ptr)
/*
FUNCTION
- bfd_cache_section_contents
-
-SYNOPSIS
- void bfd_cache_section_contents
- (asection *sec, void *contents);
-
-DESCRIPTION
- Stash @var(contents) so any following reads of @var(sec) do
- not need to decompress again.
-*/
-
-void
-bfd_cache_section_contents (asection *sec, void *contents)
-{
- if (sec->compress_status == DECOMPRESS_SECTION_ZLIB
- || sec->compress_status == DECOMPRESS_SECTION_ZSTD)
- sec->compress_status = COMPRESS_SECTION_DONE;
- sec->contents = contents;
- sec->flags |= SEC_IN_MEMORY;
-}
-
-/*
-FUNCTION
bfd_is_section_compressed_info
SYNOPSIS
diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c
index 0852b38..ec18a8a 100644
--- a/bfd/elf32-arm.c
+++ b/bfd/elf32-arm.c
@@ -20020,9 +20020,11 @@ elf32_arm_get_synthetic_symtab (bfd *abfd,
data = plt->contents;
if (data == NULL)
{
- if (!bfd_get_full_section_contents (abfd, (asection *) plt, &data) || data == NULL)
+ if (!bfd_get_full_section_contents (abfd, plt, &data)
+ || data == NULL)
return -1;
- bfd_cache_section_contents ((asection *) plt, data);
+ plt->contents = data;
+ plt->flags |= SEC_IN_MEMORY;
}
count = relplt->size / hdr->sh_entsize;