Skip to content

Commit

Permalink
zlib-gabi to zstd woes
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
amodra committed Oct 16, 2022
1 parent 4f722d4 commit 206e979
Show file tree
Hide file tree
Showing 4 changed files with 11 additions and 31 deletions.
3 changes: 0 additions & 3 deletions bfd/bfd-in2.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
4 changes: 2 additions & 2 deletions bfd/bfd.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
29 changes: 5 additions & 24 deletions bfd/compress.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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
Expand All @@ -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;
}
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -380,29 +384,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
Expand Down
6 changes: 4 additions & 2 deletions bfd/elf32-arm.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit 206e979

Please sign in to comment.