aboutsummaryrefslogtreecommitdiff
path: root/bfd/elf.c
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2022-10-04 13:14:05 +1030
committerAlan Modra <amodra@gmail.com>2022-10-04 18:42:54 +1030
commit758dd750bc6d752b290aefdd62048ca2ea5899d4 (patch)
tree3e7808b8069ea87866143d6d29d917a472ad0a5e /bfd/elf.c
parent034235cebd790d4f9a1728043a175d7d7d9338b1 (diff)
downloadgdb-758dd750bc6d752b290aefdd62048ca2ea5899d4.zip
gdb-758dd750bc6d752b290aefdd62048ca2ea5899d4.tar.gz
gdb-758dd750bc6d752b290aefdd62048ca2ea5899d4.tar.bz2
Support objcopy changing compression to or from zstd
Commit 2cac01e3ffff lacked support for objcopy changing compression style. Add that support, which meant a rewrite of bfd_compress_section_contents. In the process I've fixed some memory leaks. * compress.c (bfd_is_section_compressed_info): Rename from bfd_is_section_compressed_with_header and add ch_type param to return compression header ch_type field. Update all callers. (decompress_section_contents): Remove buffer and size params. Rewrite. Update callers. (bfd_init_section_compress_status): Free contents on failure. (bfd_compress_section): Likewise. * elf.c (_bfd_elf_make_section_from_shdr): Support objcopy changing between any of the three compression schemes. Report "unable to compress/decompress" rather than "unable to initialize compress/decompress status" on compress/decompress failures. * bfd-in2.h: Regenerate.
Diffstat (limited to 'bfd/elf.c')
-rw-r--r--bfd/elf.c93
1 files changed, 48 insertions, 45 deletions
diff --git a/bfd/elf.c b/bfd/elf.c
index 420b524..fe00e0f9 100644
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -1209,32 +1209,35 @@ _bfd_elf_make_section_from_shdr (bfd *abfd,
int compression_header_size;
bfd_size_type uncompressed_size;
unsigned int uncompressed_align_power;
+ unsigned int ch_type = 0;
bool compressed
- = bfd_is_section_compressed_with_header (abfd, newsect,
- &compression_header_size,
- &uncompressed_size,
- &uncompressed_align_power);
- if (compressed)
- {
- /* Compressed section. Check if we should decompress. */
- if ((abfd->flags & BFD_DECOMPRESS))
- action = decompress;
- }
-
- /* Compress the uncompressed section or convert from/to .zdebug*
- section. Check if we should compress. */
- if (action == nothing)
- {
- if (newsect->size != 0
- && (abfd->flags & BFD_COMPRESS)
- && compression_header_size >= 0
- && uncompressed_size > 0
- && (!compressed
- || ((compression_header_size > 0)
- != ((abfd->flags & BFD_COMPRESS_GABI) != 0))))
+ = bfd_is_section_compressed_info (abfd, newsect,
+ &compression_header_size,
+ &uncompressed_size,
+ &uncompressed_align_power,
+ &ch_type);
+
+ /* Should we decompress? */
+ if ((abfd->flags & BFD_DECOMPRESS) != 0 && compressed)
+ action = decompress;
+
+ /* Should we compress? Or convert to a different compression? */
+ else if ((abfd->flags & BFD_COMPRESS) != 0
+ && newsect->size != 0
+ && compression_header_size >= 0
+ && uncompressed_size > 0)
+ {
+ if (!compressed)
action = compress;
else
- return true;
+ {
+ unsigned int new_ch_type = 0;
+ if ((abfd->flags & BFD_COMPRESS_GABI) != 0)
+ new_ch_type = ((abfd->flags & BFD_COMPRESS_ZSTD) != 0
+ ? ELFCOMPRESS_ZSTD : ELFCOMPRESS_ZLIB);
+ if (new_ch_type != ch_type)
+ action = compress;
+ }
}
if (action == compress)
@@ -1243,20 +1246,17 @@ _bfd_elf_make_section_from_shdr (bfd *abfd,
{
_bfd_error_handler
/* xgettext:c-format */
- (_("%pB: unable to initialize compress status for section %s"),
- abfd, name);
+ (_("%pB: unable to compress section %s"), abfd, name);
return false;
}
}
- else
+ else if (action == decompress)
{
if (!bfd_init_section_decompress_status (abfd, newsect))
{
_bfd_error_handler
/* xgettext:c-format */
- (_("%pB: unable to initialize decompress status"
- " for section %s"),
- abfd, name);
+ (_("%pB: unable to decompress section %s"), abfd, name);
return false;
}
#ifndef HAVE_ZSTD
@@ -1273,26 +1273,29 @@ _bfd_elf_make_section_from_shdr (bfd *abfd,
#endif
}
- if (abfd->is_linker_input)
+ if (action != nothing)
{
- if (name[1] == 'z'
- && (action == decompress
- || (action == compress
- && (abfd->flags & BFD_COMPRESS_GABI) != 0)))
+ if (abfd->is_linker_input)
{
- /* Convert section name from .zdebug_* to .debug_* so
- that linker will consider this section as a debug
- section. */
- char *new_name = convert_zdebug_to_debug (abfd, name);
- if (new_name == NULL)
- return false;
- bfd_rename_section (newsect, new_name);
+ if (name[1] == 'z'
+ && (action == decompress
+ || (action == compress
+ && (abfd->flags & BFD_COMPRESS_GABI) != 0)))
+ {
+ /* Convert section name from .zdebug_* to .debug_* so
+ that linker will consider this section as a debug
+ section. */
+ char *new_name = convert_zdebug_to_debug (abfd, name);
+ if (new_name == NULL)
+ return false;
+ bfd_rename_section (newsect, new_name);
+ }
}
+ else
+ /* For objdump, don't rename the section. For objcopy, delay
+ section rename to elf_fake_sections. */
+ newsect->flags |= SEC_ELF_RENAME;
}
- else
- /* For objdump, don't rename the section. For objcopy, delay
- section rename to elf_fake_sections. */
- newsect->flags |= SEC_ELF_RENAME;
}
/* GCC uses .gnu.lto_.lto.<some_hash> as a LTO bytecode information