Home | History | Annotate | Line # | Download | only in bfd
      1   1.1  christos /* Compressed section support (intended for debug sections).
      2  1.11  christos    Copyright (C) 2008-2024 Free Software Foundation, Inc.
      3   1.1  christos 
      4   1.1  christos    This file is part of BFD, the Binary File Descriptor library.
      5   1.1  christos 
      6   1.1  christos    This program is free software; you can redistribute it and/or modify
      7   1.1  christos    it under the terms of the GNU General Public License as published by
      8   1.1  christos    the Free Software Foundation; either version 3 of the License, or
      9   1.1  christos    (at your option) any later version.
     10   1.1  christos 
     11   1.1  christos    This program is distributed in the hope that it will be useful,
     12   1.1  christos    but WITHOUT ANY WARRANTY; without even the implied warranty of
     13   1.1  christos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14   1.1  christos    GNU General Public License for more details.
     15   1.1  christos 
     16   1.1  christos    You should have received a copy of the GNU General Public License
     17   1.1  christos    along with this program; if not, write to the Free Software
     18   1.1  christos    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
     19   1.1  christos    MA 02110-1301, USA.  */
     20   1.1  christos 
     21   1.1  christos #include "sysdep.h"
     22   1.5  christos #include <zlib.h>
     23  1.10  christos #ifdef HAVE_ZSTD
     24  1.10  christos #include <zstd.h>
     25  1.10  christos #endif
     26   1.1  christos #include "bfd.h"
     27  1.10  christos #include "elf-bfd.h"
     28   1.1  christos #include "libbfd.h"
     29   1.3  christos #include "safe-ctype.h"
     30  1.10  christos #include "libiberty.h"
     31   1.1  christos 
     32   1.5  christos #define MAX_COMPRESSION_HEADER_SIZE 24
     33   1.5  christos 
     34  1.10  christos /*
     35  1.11  christos EXTERNAL
     36  1.10  christos .{* Types of compressed DWARF debug sections.  *}
     37  1.10  christos .enum compressed_debug_section_type
     38  1.10  christos .{
     39  1.10  christos .  COMPRESS_DEBUG_NONE = 0,
     40  1.10  christos .  COMPRESS_DEBUG_GNU_ZLIB = 1 << 1,
     41  1.10  christos .  COMPRESS_DEBUG_GABI_ZLIB = 1 << 2,
     42  1.10  christos .  COMPRESS_DEBUG_ZSTD = 1 << 3,
     43  1.10  christos .  COMPRESS_UNKNOWN = 1 << 4
     44  1.10  christos .};
     45  1.10  christos .
     46  1.10  christos .{* Tuple for compressed_debug_section_type and their name.  *}
     47  1.10  christos .struct compressed_type_tuple
     48  1.10  christos .{
     49  1.10  christos .  enum compressed_debug_section_type type;
     50  1.10  christos .  const char *name;
     51  1.10  christos .};
     52  1.10  christos .
     53  1.10  christos .{* Compression header ch_type values.  *}
     54  1.10  christos .enum compression_type
     55  1.10  christos .{
     56  1.10  christos .  ch_none = 0,
     57  1.10  christos .  ch_compress_zlib = 1	,	{* Compressed with zlib.  *}
     58  1.10  christos .  ch_compress_zstd = 2		{* Compressed with zstd (www.zstandard.org).  *}
     59  1.10  christos .};
     60  1.10  christos .
     61  1.10  christos .static inline char *
     62  1.10  christos .bfd_debug_name_to_zdebug (bfd *abfd, const char *name)
     63  1.10  christos .{
     64  1.10  christos .  size_t len = strlen (name);
     65  1.10  christos .  char *new_name = (char *) bfd_alloc (abfd, len + 2);
     66  1.10  christos .  if (new_name == NULL)
     67  1.10  christos .    return NULL;
     68  1.10  christos .  new_name[0] = '.';
     69  1.10  christos .  new_name[1] = 'z';
     70  1.10  christos .  memcpy (new_name + 2, name + 1, len);
     71  1.10  christos .  return new_name;
     72  1.10  christos .}
     73  1.10  christos .
     74  1.10  christos .static inline char *
     75  1.10  christos .bfd_zdebug_name_to_debug (bfd *abfd, const char *name)
     76  1.10  christos .{
     77  1.10  christos .  size_t len = strlen (name);
     78  1.10  christos .  char *new_name = (char *) bfd_alloc (abfd, len);
     79  1.10  christos .  if (new_name == NULL)
     80  1.10  christos .    return NULL;
     81  1.10  christos .  new_name[0] = '.';
     82  1.10  christos .  memcpy (new_name + 1, name + 2, len - 1);
     83  1.10  christos .  return new_name;
     84  1.10  christos .}
     85  1.10  christos .
     86  1.10  christos */
     87  1.10  christos 
     88  1.10  christos /* Display texts for type of compressed DWARF debug sections.  */
     89  1.10  christos static const struct compressed_type_tuple compressed_debug_section_names[] =
     90  1.10  christos {
     91  1.10  christos   { COMPRESS_DEBUG_NONE, "none" },
     92  1.10  christos   { COMPRESS_DEBUG_GABI_ZLIB, "zlib" },
     93  1.10  christos   { COMPRESS_DEBUG_GNU_ZLIB, "zlib-gnu" },
     94  1.10  christos   { COMPRESS_DEBUG_GABI_ZLIB, "zlib-gabi" },
     95  1.10  christos   { COMPRESS_DEBUG_ZSTD, "zstd" },
     96  1.10  christos };
     97  1.10  christos 
     98  1.10  christos /*
     99  1.10  christos FUNCTION
    100  1.10  christos 	bfd_get_compression_algorithm
    101  1.10  christos SYNOPSIS
    102  1.10  christos 	enum compressed_debug_section_type
    103  1.10  christos 	  bfd_get_compression_algorithm (const char *name);
    104  1.10  christos DESCRIPTION
    105  1.10  christos 	Return compressed_debug_section_type from a string representation.
    106  1.10  christos */
    107  1.10  christos enum compressed_debug_section_type
    108  1.10  christos bfd_get_compression_algorithm (const char *name)
    109  1.10  christos {
    110  1.10  christos   for (unsigned i = 0; i < ARRAY_SIZE (compressed_debug_section_names); ++i)
    111  1.10  christos     if (strcasecmp (compressed_debug_section_names[i].name, name) == 0)
    112  1.10  christos       return compressed_debug_section_names[i].type;
    113  1.10  christos 
    114  1.10  christos   return COMPRESS_UNKNOWN;
    115  1.10  christos }
    116  1.10  christos 
    117  1.10  christos /*
    118  1.10  christos FUNCTION
    119  1.10  christos 	bfd_get_compression_algorithm_name
    120  1.10  christos SYNOPSIS
    121  1.10  christos 	const char *bfd_get_compression_algorithm_name
    122  1.10  christos 	  (enum compressed_debug_section_type type);
    123  1.10  christos DESCRIPTION
    124  1.10  christos 	Return compression algorithm name based on the type.
    125  1.10  christos */
    126  1.10  christos const char *
    127  1.10  christos bfd_get_compression_algorithm_name (enum compressed_debug_section_type type)
    128  1.10  christos {
    129  1.10  christos   for (unsigned i = 0; i < ARRAY_SIZE (compressed_debug_section_names); ++i)
    130  1.10  christos     if (type == compressed_debug_section_names[i].type)
    131  1.10  christos       return compressed_debug_section_names[i].name;
    132  1.10  christos 
    133  1.10  christos   return NULL;
    134  1.10  christos }
    135  1.10  christos 
    136  1.10  christos /*
    137  1.10  christos FUNCTION
    138  1.10  christos 	bfd_update_compression_header
    139  1.10  christos 
    140  1.10  christos SYNOPSIS
    141  1.10  christos 	void bfd_update_compression_header
    142  1.10  christos 	  (bfd *abfd, bfd_byte *contents, asection *sec);
    143  1.10  christos 
    144  1.10  christos DESCRIPTION
    145  1.10  christos 	Set the compression header at CONTENTS of SEC in ABFD and update
    146  1.10  christos 	elf_section_flags for compression.
    147  1.10  christos */
    148  1.10  christos 
    149  1.10  christos void
    150  1.10  christos bfd_update_compression_header (bfd *abfd, bfd_byte *contents,
    151  1.10  christos 			       asection *sec)
    152  1.10  christos {
    153  1.10  christos   if ((abfd->flags & BFD_COMPRESS) == 0)
    154  1.10  christos     abort ();
    155  1.10  christos 
    156  1.10  christos   switch (bfd_get_flavour (abfd))
    157  1.10  christos     {
    158  1.10  christos     case bfd_target_elf_flavour:
    159  1.10  christos       if ((abfd->flags & BFD_COMPRESS_GABI) != 0)
    160  1.10  christos 	{
    161  1.10  christos 	  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
    162  1.10  christos 	  struct bfd_elf_section_data * esd = elf_section_data (sec);
    163  1.10  christos 	  enum compression_type ch_type = (abfd->flags & BFD_COMPRESS_ZSTD
    164  1.10  christos 					   ? ch_compress_zstd
    165  1.10  christos 					   : ch_compress_zlib);
    166  1.10  christos 
    167  1.10  christos 	  /* Set the SHF_COMPRESSED bit.  */
    168  1.10  christos 	  elf_section_flags (sec) |= SHF_COMPRESSED;
    169  1.10  christos 
    170  1.10  christos 	  if (bed->s->elfclass == ELFCLASS32)
    171  1.10  christos 	    {
    172  1.10  christos 	      Elf32_External_Chdr *echdr = (Elf32_External_Chdr *) contents;
    173  1.10  christos 	      bfd_put_32 (abfd, ch_type, &echdr->ch_type);
    174  1.10  christos 	      bfd_put_32 (abfd, sec->size, &echdr->ch_size);
    175  1.10  christos 	      bfd_put_32 (abfd, 1u << sec->alignment_power,
    176  1.10  christos 			  &echdr->ch_addralign);
    177  1.10  christos 	      /* bfd_log2 (alignof (Elf32_Chdr)) */
    178  1.10  christos 	      bfd_set_section_alignment (sec, 2);
    179  1.10  christos 	      esd->this_hdr.sh_addralign = 4;
    180  1.10  christos 	    }
    181  1.10  christos 	  else
    182  1.10  christos 	    {
    183  1.10  christos 	      Elf64_External_Chdr *echdr = (Elf64_External_Chdr *) contents;
    184  1.10  christos 	      bfd_put_32 (abfd, ch_type, &echdr->ch_type);
    185  1.10  christos 	      bfd_put_32 (abfd, 0, &echdr->ch_reserved);
    186  1.10  christos 	      bfd_put_64 (abfd, sec->size, &echdr->ch_size);
    187  1.10  christos 	      bfd_put_64 (abfd, UINT64_C (1) << sec->alignment_power,
    188  1.10  christos 			  &echdr->ch_addralign);
    189  1.10  christos 	      /* bfd_log2 (alignof (Elf64_Chdr)) */
    190  1.10  christos 	      bfd_set_section_alignment (sec, 3);
    191  1.10  christos 	      esd->this_hdr.sh_addralign = 8;
    192  1.10  christos 	    }
    193  1.10  christos 	  break;
    194  1.10  christos 	}
    195  1.10  christos 
    196  1.10  christos       /* Clear the SHF_COMPRESSED bit.  */
    197  1.10  christos       elf_section_flags (sec) &= ~SHF_COMPRESSED;
    198  1.10  christos       /* Fall through.  */
    199  1.10  christos 
    200  1.10  christos     default:
    201  1.10  christos       /* Write the zlib header.  It should be "ZLIB" followed by
    202  1.10  christos 	 the uncompressed section size, 8 bytes in big-endian
    203  1.10  christos 	 order.  */
    204  1.10  christos       memcpy (contents, "ZLIB", 4);
    205  1.10  christos       bfd_putb64 (sec->size, contents + 4);
    206  1.10  christos       /* No way to keep the original alignment, just use 1 always. */
    207  1.10  christos       bfd_set_section_alignment (sec, 0);
    208  1.10  christos       break;
    209  1.10  christos     }
    210  1.10  christos }
    211  1.10  christos 
    212  1.10  christos /* Check the compression header at CONTENTS of SEC in ABFD and store the
    213  1.10  christos    ch_type in CH_TYPE, uncompressed size in UNCOMPRESSED_SIZE, and the
    214  1.10  christos    uncompressed data alignment in UNCOMPRESSED_ALIGNMENT_POWER if the
    215  1.10  christos    compression header is valid.  */
    216  1.10  christos 
    217  1.10  christos static bool
    218  1.10  christos bfd_check_compression_header (bfd *abfd, bfd_byte *contents,
    219  1.10  christos 			      asection *sec,
    220  1.10  christos 			      enum compression_type *ch_type,
    221  1.10  christos 			      bfd_size_type *uncompressed_size,
    222  1.10  christos 			      unsigned int *uncompressed_alignment_power)
    223  1.10  christos {
    224  1.10  christos   if (bfd_get_flavour (abfd) == bfd_target_elf_flavour
    225  1.10  christos       && (elf_section_flags (sec) & SHF_COMPRESSED) != 0)
    226  1.10  christos     {
    227  1.10  christos       Elf_Internal_Chdr chdr;
    228  1.10  christos       const struct elf_backend_data *bed = get_elf_backend_data (abfd);
    229  1.10  christos       if (bed->s->elfclass == ELFCLASS32)
    230  1.10  christos 	{
    231  1.10  christos 	  Elf32_External_Chdr *echdr = (Elf32_External_Chdr *) contents;
    232  1.10  christos 	  chdr.ch_type = bfd_get_32 (abfd, &echdr->ch_type);
    233  1.10  christos 	  chdr.ch_size = bfd_get_32 (abfd, &echdr->ch_size);
    234  1.10  christos 	  chdr.ch_addralign = bfd_get_32 (abfd, &echdr->ch_addralign);
    235  1.10  christos 	}
    236  1.10  christos       else
    237  1.10  christos 	{
    238  1.10  christos 	  Elf64_External_Chdr *echdr = (Elf64_External_Chdr *) contents;
    239  1.10  christos 	  chdr.ch_type = bfd_get_32 (abfd, &echdr->ch_type);
    240  1.10  christos 	  chdr.ch_size = bfd_get_64 (abfd, &echdr->ch_size);
    241  1.10  christos 	  chdr.ch_addralign = bfd_get_64 (abfd, &echdr->ch_addralign);
    242  1.10  christos 	}
    243  1.10  christos       *ch_type = chdr.ch_type;
    244  1.10  christos       if ((chdr.ch_type == ch_compress_zlib
    245  1.10  christos 	   || chdr.ch_type == ch_compress_zstd)
    246  1.10  christos 	  && chdr.ch_addralign == (chdr.ch_addralign & -chdr.ch_addralign))
    247  1.10  christos 	{
    248  1.10  christos 	  *uncompressed_size = chdr.ch_size;
    249  1.10  christos 	  *uncompressed_alignment_power = bfd_log2 (chdr.ch_addralign);
    250  1.10  christos 	  return true;
    251  1.10  christos 	}
    252  1.10  christos     }
    253  1.10  christos 
    254  1.10  christos   return false;
    255  1.10  christos }
    256  1.10  christos 
    257  1.10  christos /*
    258  1.10  christos FUNCTION
    259  1.10  christos 	bfd_get_compression_header_size
    260  1.10  christos 
    261  1.10  christos SYNOPSIS
    262  1.10  christos 	int bfd_get_compression_header_size (bfd *abfd, asection *sec);
    263  1.10  christos 
    264  1.10  christos DESCRIPTION
    265  1.10  christos 	Return the size of the compression header of SEC in ABFD.
    266  1.10  christos */
    267  1.10  christos 
    268  1.10  christos int
    269  1.10  christos bfd_get_compression_header_size (bfd *abfd, asection *sec)
    270  1.10  christos {
    271  1.10  christos   if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
    272  1.10  christos     {
    273  1.10  christos       if (sec == NULL)
    274  1.10  christos 	{
    275  1.10  christos 	  if (!(abfd->flags & BFD_COMPRESS_GABI))
    276  1.10  christos 	    return 0;
    277  1.10  christos 	}
    278  1.10  christos       else if (!(elf_section_flags (sec) & SHF_COMPRESSED))
    279  1.10  christos 	return 0;
    280  1.10  christos 
    281  1.10  christos       if (get_elf_backend_data (abfd)->s->elfclass == ELFCLASS32)
    282  1.10  christos 	return sizeof (Elf32_External_Chdr);
    283  1.10  christos       else
    284  1.10  christos 	return sizeof (Elf64_External_Chdr);
    285  1.10  christos     }
    286  1.10  christos 
    287  1.10  christos   return 0;
    288  1.10  christos }
    289  1.10  christos 
    290  1.10  christos /*
    291  1.10  christos FUNCTION
    292  1.10  christos 	bfd_convert_section_setup
    293  1.10  christos 
    294  1.10  christos SYNOPSIS
    295  1.10  christos 	bool bfd_convert_section_setup
    296  1.10  christos 	  (bfd *ibfd, asection *isec, bfd *obfd,
    297  1.10  christos 	   const char **new_name, bfd_size_type *new_size);
    298  1.10  christos 
    299  1.10  christos DESCRIPTION
    300  1.10  christos 	Do early setup for objcopy, when copying @var{isec} in input
    301  1.10  christos 	BFD @var{ibfd} to output BFD @var{obfd}.  Returns the name and
    302  1.10  christos 	size of the output section.
    303  1.10  christos */
    304  1.10  christos 
    305  1.10  christos bool
    306  1.10  christos bfd_convert_section_setup (bfd *ibfd, asection *isec, bfd *obfd,
    307  1.10  christos 			   const char **new_name, bfd_size_type *new_size)
    308  1.10  christos {
    309  1.10  christos   bfd_size_type hdr_size;
    310  1.10  christos 
    311  1.10  christos   if ((isec->flags & SEC_DEBUGGING) != 0
    312  1.10  christos       && (isec->flags & SEC_HAS_CONTENTS) != 0)
    313  1.10  christos     {
    314  1.10  christos       const char *name = *new_name;
    315  1.10  christos 
    316  1.10  christos       if ((obfd->flags & (BFD_DECOMPRESS | BFD_COMPRESS_GABI)) != 0)
    317  1.10  christos 	{
    318  1.10  christos 	  /* When we decompress or compress with SHF_COMPRESSED,
    319  1.10  christos 	     convert section name from .zdebug_* to .debug_*.  */
    320  1.10  christos 	  if (startswith (name, ".zdebug_"))
    321  1.10  christos 	    {
    322  1.10  christos 	      name = bfd_zdebug_name_to_debug (obfd, name);
    323  1.10  christos 	      if (name == NULL)
    324  1.10  christos 		return false;
    325  1.10  christos 	    }
    326  1.10  christos 	}
    327  1.10  christos 
    328  1.10  christos       /* PR binutils/18087: Compression does not always make a
    329  1.10  christos 	 section smaller.  So only rename the section when
    330  1.10  christos 	 compression has actually taken place.  If input section
    331  1.10  christos 	 name is .zdebug_*, we should never compress it again.  */
    332  1.10  christos       else if (isec->compress_status == COMPRESS_SECTION_DONE
    333  1.10  christos 	       && startswith (name, ".debug_"))
    334  1.10  christos 	{
    335  1.10  christos 	  name = bfd_debug_name_to_zdebug (obfd, name);
    336  1.10  christos 	  if (name == NULL)
    337  1.10  christos 	    return false;
    338  1.10  christos 	}
    339  1.10  christos       *new_name = name;
    340  1.10  christos     }
    341  1.10  christos   *new_size = bfd_section_size (isec);
    342  1.10  christos 
    343  1.10  christos   /* Do nothing if either input or output aren't ELF.  */
    344  1.10  christos   if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
    345  1.10  christos       || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
    346  1.10  christos     return true;
    347  1.10  christos 
    348  1.10  christos   /* Do nothing if ELF classes of input and output are the same. */
    349  1.10  christos   if (get_elf_backend_data (ibfd)->s->elfclass
    350  1.10  christos       == get_elf_backend_data (obfd)->s->elfclass)
    351  1.10  christos     return true;
    352  1.10  christos 
    353  1.10  christos   /* Convert GNU property size.  */
    354  1.10  christos   if (startswith (isec->name, NOTE_GNU_PROPERTY_SECTION_NAME))
    355  1.10  christos     {
    356  1.10  christos       *new_size = _bfd_elf_convert_gnu_property_size (ibfd, obfd);
    357  1.10  christos       return true;
    358  1.10  christos     }
    359  1.10  christos 
    360  1.10  christos   /* Do nothing if input file will be decompressed.  */
    361  1.10  christos   if ((ibfd->flags & BFD_DECOMPRESS))
    362  1.10  christos     return true;
    363  1.10  christos 
    364  1.10  christos   /* Do nothing if the input section isn't a SHF_COMPRESSED section. */
    365  1.10  christos   hdr_size = bfd_get_compression_header_size (ibfd, isec);
    366  1.10  christos   if (hdr_size == 0)
    367  1.10  christos     return true;
    368  1.10  christos 
    369  1.10  christos   /* Adjust the size of the output SHF_COMPRESSED section.  */
    370  1.10  christos   if (hdr_size == sizeof (Elf32_External_Chdr))
    371  1.10  christos     *new_size += sizeof (Elf64_External_Chdr) - sizeof (Elf32_External_Chdr);
    372  1.10  christos   else
    373  1.10  christos     *new_size -= sizeof (Elf64_External_Chdr) - sizeof (Elf32_External_Chdr);
    374  1.10  christos   return true;
    375  1.10  christos }
    376  1.10  christos 
    377  1.10  christos /*
    378  1.10  christos FUNCTION
    379  1.10  christos 	bfd_convert_section_contents
    380  1.10  christos 
    381  1.10  christos SYNOPSIS
    382  1.10  christos 	bool bfd_convert_section_contents
    383  1.10  christos 	  (bfd *ibfd, asection *isec, bfd *obfd,
    384  1.10  christos 	   bfd_byte **ptr, bfd_size_type *ptr_size);
    385  1.10  christos 
    386  1.10  christos DESCRIPTION
    387  1.10  christos 	Convert the contents, stored in @var{*ptr}, of the section
    388  1.10  christos 	@var{isec} in input BFD @var{ibfd} to output BFD @var{obfd}
    389  1.10  christos 	if needed.  The original buffer pointed to by @var{*ptr} may
    390  1.10  christos 	be freed and @var{*ptr} is returned with memory malloc'd by this
    391  1.10  christos 	function, and the new size written to @var{ptr_size}.
    392  1.10  christos */
    393  1.10  christos 
    394  1.10  christos bool
    395  1.10  christos bfd_convert_section_contents (bfd *ibfd, sec_ptr isec, bfd *obfd,
    396  1.10  christos 			      bfd_byte **ptr, bfd_size_type *ptr_size)
    397  1.10  christos {
    398  1.10  christos   bfd_byte *contents;
    399  1.10  christos   bfd_size_type ihdr_size, ohdr_size, size;
    400  1.10  christos   Elf_Internal_Chdr chdr;
    401  1.10  christos   bool use_memmove;
    402  1.10  christos 
    403  1.10  christos   /* Do nothing if either input or output aren't ELF.  */
    404  1.10  christos   if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
    405  1.10  christos       || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
    406  1.10  christos     return true;
    407  1.10  christos 
    408  1.10  christos   /* Do nothing if ELF classes of input and output are the same.  */
    409  1.10  christos   if (get_elf_backend_data (ibfd)->s->elfclass
    410  1.10  christos       == get_elf_backend_data (obfd)->s->elfclass)
    411  1.10  christos     return true;
    412  1.10  christos 
    413  1.10  christos   /* Convert GNU properties.  */
    414  1.10  christos   if (startswith (isec->name, NOTE_GNU_PROPERTY_SECTION_NAME))
    415  1.10  christos     return _bfd_elf_convert_gnu_properties (ibfd, isec, obfd, ptr,
    416  1.10  christos 					    ptr_size);
    417  1.10  christos 
    418  1.10  christos   /* Do nothing if input file will be decompressed.  */
    419  1.10  christos   if ((ibfd->flags & BFD_DECOMPRESS))
    420  1.10  christos     return true;
    421  1.10  christos 
    422  1.10  christos   /* Do nothing if the input section isn't a SHF_COMPRESSED section.  */
    423  1.10  christos   ihdr_size = bfd_get_compression_header_size (ibfd, isec);
    424  1.10  christos   if (ihdr_size == 0)
    425  1.10  christos     return true;
    426  1.10  christos 
    427  1.10  christos   /* PR 25221.  Check for corrupt input sections.  */
    428  1.10  christos   if (ihdr_size > bfd_get_section_limit (ibfd, isec))
    429  1.10  christos     /* FIXME: Issue a warning about a corrupt
    430  1.10  christos        compression header size field ?  */
    431  1.10  christos     return false;
    432  1.10  christos 
    433  1.10  christos   contents = *ptr;
    434  1.10  christos 
    435  1.10  christos   /* Convert the contents of the input SHF_COMPRESSED section to
    436  1.10  christos      output.  Get the input compression header and the size of the
    437  1.10  christos      output compression header.  */
    438  1.10  christos   if (ihdr_size == sizeof (Elf32_External_Chdr))
    439  1.10  christos     {
    440  1.10  christos       Elf32_External_Chdr *echdr = (Elf32_External_Chdr *) contents;
    441  1.10  christos       chdr.ch_type = bfd_get_32 (ibfd, &echdr->ch_type);
    442  1.10  christos       chdr.ch_size = bfd_get_32 (ibfd, &echdr->ch_size);
    443  1.10  christos       chdr.ch_addralign = bfd_get_32 (ibfd, &echdr->ch_addralign);
    444  1.10  christos 
    445  1.10  christos       ohdr_size = sizeof (Elf64_External_Chdr);
    446  1.10  christos 
    447  1.10  christos       use_memmove = false;
    448  1.10  christos     }
    449  1.10  christos   else if (ihdr_size != sizeof (Elf64_External_Chdr))
    450  1.10  christos     {
    451  1.10  christos       /* FIXME: Issue a warning about a corrupt
    452  1.10  christos 	 compression header size field ?  */
    453  1.10  christos       return false;
    454  1.10  christos     }
    455  1.10  christos   else
    456  1.10  christos     {
    457  1.10  christos       Elf64_External_Chdr *echdr = (Elf64_External_Chdr *) contents;
    458  1.10  christos       chdr.ch_type = bfd_get_32 (ibfd, &echdr->ch_type);
    459  1.10  christos       chdr.ch_size = bfd_get_64 (ibfd, &echdr->ch_size);
    460  1.10  christos       chdr.ch_addralign = bfd_get_64 (ibfd, &echdr->ch_addralign);
    461  1.10  christos 
    462  1.10  christos       ohdr_size = sizeof (Elf32_External_Chdr);
    463  1.10  christos       use_memmove = true;
    464  1.10  christos     }
    465  1.10  christos 
    466  1.10  christos   size = bfd_section_size (isec) - ihdr_size + ohdr_size;
    467  1.10  christos   if (!use_memmove)
    468  1.10  christos     {
    469  1.10  christos       contents = (bfd_byte *) bfd_malloc (size);
    470  1.10  christos       if (contents == NULL)
    471  1.10  christos 	return false;
    472  1.10  christos     }
    473  1.10  christos 
    474  1.10  christos   /* Write out the output compression header.  */
    475  1.10  christos   if (ohdr_size == sizeof (Elf32_External_Chdr))
    476  1.10  christos     {
    477  1.10  christos       Elf32_External_Chdr *echdr = (Elf32_External_Chdr *) contents;
    478  1.10  christos       bfd_put_32 (obfd, chdr.ch_type, &echdr->ch_type);
    479  1.10  christos       bfd_put_32 (obfd, chdr.ch_size, &echdr->ch_size);
    480  1.10  christos       bfd_put_32 (obfd, chdr.ch_addralign, &echdr->ch_addralign);
    481  1.10  christos     }
    482  1.10  christos   else
    483  1.10  christos     {
    484  1.10  christos       Elf64_External_Chdr *echdr = (Elf64_External_Chdr *) contents;
    485  1.10  christos       bfd_put_32 (obfd, chdr.ch_type, &echdr->ch_type);
    486  1.10  christos       bfd_put_32 (obfd, 0, &echdr->ch_reserved);
    487  1.10  christos       bfd_put_64 (obfd, chdr.ch_size, &echdr->ch_size);
    488  1.10  christos       bfd_put_64 (obfd, chdr.ch_addralign, &echdr->ch_addralign);
    489  1.10  christos     }
    490  1.10  christos 
    491  1.10  christos   /* Copy the compressed contents.  */
    492  1.10  christos   if (use_memmove)
    493  1.10  christos     memmove (contents + ohdr_size, *ptr + ihdr_size, size - ohdr_size);
    494  1.10  christos   else
    495  1.10  christos     {
    496  1.10  christos       memcpy (contents + ohdr_size, *ptr + ihdr_size, size - ohdr_size);
    497  1.10  christos       free (*ptr);
    498  1.10  christos       *ptr = contents;
    499  1.10  christos     }
    500  1.10  christos 
    501  1.10  christos   *ptr_size = size;
    502  1.10  christos   return true;
    503  1.10  christos }
    504  1.10  christos 
    505  1.10  christos static bool
    506  1.10  christos decompress_contents (bool is_zstd, bfd_byte *compressed_buffer,
    507   1.1  christos 		     bfd_size_type compressed_size,
    508   1.1  christos 		     bfd_byte *uncompressed_buffer,
    509   1.1  christos 		     bfd_size_type uncompressed_size)
    510   1.1  christos {
    511  1.10  christos   if (is_zstd)
    512  1.10  christos     {
    513  1.10  christos #ifdef HAVE_ZSTD
    514  1.10  christos       size_t ret = ZSTD_decompress (uncompressed_buffer, uncompressed_size,
    515  1.10  christos 				    compressed_buffer, compressed_size);
    516  1.10  christos       return !ZSTD_isError (ret);
    517  1.10  christos #endif
    518  1.10  christos     }
    519  1.10  christos 
    520   1.1  christos   z_stream strm;
    521   1.1  christos   int rc;
    522   1.1  christos 
    523   1.1  christos   /* It is possible the section consists of several compressed
    524   1.1  christos      buffers concatenated together, so we uncompress in a loop.  */
    525   1.5  christos   /* PR 18313: The state field in the z_stream structure is supposed
    526   1.5  christos      to be invisible to the user (ie us), but some compilers will
    527   1.5  christos      still complain about it being used without initialisation.  So
    528   1.5  christos      we first zero the entire z_stream structure and then set the fields
    529   1.5  christos      that we need.  */
    530   1.5  christos   memset (& strm, 0, sizeof strm);
    531   1.5  christos   strm.avail_in = compressed_size;
    532   1.5  christos   strm.next_in = (Bytef*) compressed_buffer;
    533   1.1  christos   strm.avail_out = uncompressed_size;
    534  1.10  christos   /* FIXME: strm.avail_in and strm.avail_out are typically unsigned
    535  1.10  christos      int.  Supporting sizes that don't fit in an unsigned int is
    536  1.10  christos      possible but will require some rewriting of this function.  */
    537  1.10  christos   if (strm.avail_in != compressed_size || strm.avail_out != uncompressed_size)
    538  1.10  christos     return false;
    539   1.1  christos 
    540   1.1  christos   BFD_ASSERT (Z_OK == 0);
    541   1.1  christos   rc = inflateInit (&strm);
    542   1.1  christos   while (strm.avail_in > 0 && strm.avail_out > 0)
    543   1.1  christos     {
    544   1.1  christos       if (rc != Z_OK)
    545   1.1  christos 	break;
    546   1.1  christos       strm.next_out = ((Bytef*) uncompressed_buffer
    547   1.8  christos 		       + (uncompressed_size - strm.avail_out));
    548   1.1  christos       rc = inflate (&strm, Z_FINISH);
    549   1.1  christos       if (rc != Z_STREAM_END)
    550   1.1  christos 	break;
    551   1.1  christos       rc = inflateReset (&strm);
    552   1.1  christos     }
    553  1.10  christos   return inflateEnd (&strm) == Z_OK && rc == Z_OK && strm.avail_out == 0;
    554   1.1  christos }
    555   1.1  christos 
    556  1.10  christos /* Compress section contents using zlib/zstd and store
    557   1.5  christos    as the contents field.  This function assumes the contents
    558   1.5  christos    field was allocated using bfd_malloc() or equivalent.
    559   1.5  christos 
    560   1.5  christos    Return the uncompressed size if the full section contents is
    561  1.11  christos    compressed successfully.  Otherwise return (bfd_size_type) -1.  */
    562   1.5  christos 
    563   1.5  christos static bfd_size_type
    564  1.10  christos bfd_compress_section_contents (bfd *abfd, sec_ptr sec)
    565   1.1  christos {
    566  1.10  christos   bfd_byte *input_buffer;
    567   1.1  christos   uLong compressed_size;
    568   1.5  christos   bfd_byte *buffer;
    569   1.5  christos   bfd_size_type buffer_size;
    570   1.5  christos   int zlib_size = 0;
    571  1.10  christos   int orig_header_size;
    572  1.10  christos   bfd_size_type uncompressed_size;
    573  1.10  christos   unsigned int uncompressed_alignment_pow;
    574  1.10  christos   enum compression_type ch_type = ch_none;
    575  1.10  christos   int new_header_size = bfd_get_compression_header_size (abfd, NULL);
    576  1.10  christos   bool compressed
    577  1.10  christos     = bfd_is_section_compressed_info (abfd, sec,
    578  1.10  christos 				      &orig_header_size,
    579  1.10  christos 				      &uncompressed_size,
    580  1.10  christos 				      &uncompressed_alignment_pow,
    581  1.10  christos 				      &ch_type);
    582  1.10  christos   bool update = false;
    583  1.10  christos 
    584  1.10  christos   /* We shouldn't be trying to decompress unsupported compressed sections.  */
    585  1.10  christos   if (compressed && orig_header_size < 0)
    586  1.10  christos     abort ();
    587   1.5  christos 
    588  1.11  christos   /* PR 31455: Check for a corrupt uncompressed size.  */
    589  1.11  christos   if (uncompressed_size == (bfd_size_type) -1)
    590  1.11  christos     return uncompressed_size;
    591  1.11  christos 
    592   1.5  christos   /* Either ELF compression header or the 12-byte, "ZLIB" + 8-byte size,
    593   1.5  christos      overhead in .zdebug* section.  */
    594  1.10  christos   if (!new_header_size)
    595  1.10  christos     new_header_size = 12;
    596  1.10  christos   if (ch_type == ch_none)
    597  1.10  christos     orig_header_size = 12;
    598   1.5  christos 
    599  1.10  christos   input_buffer = sec->contents;
    600   1.5  christos   if (compressed)
    601   1.5  christos     {
    602  1.10  christos       zlib_size = sec->size - orig_header_size;
    603  1.10  christos       compressed_size = zlib_size + new_header_size;
    604  1.10  christos 
    605  1.10  christos       /* If we are converting between zlib-gnu and zlib-gabi then the
    606  1.10  christos 	 compressed contents just need to be moved.  */
    607  1.10  christos       update = (ch_type < ch_compress_zstd
    608  1.10  christos 		&& (abfd->flags & BFD_COMPRESS_ZSTD) == 0);
    609  1.10  christos 
    610  1.10  christos       /* Uncompress when not just moving contents or when compressed
    611  1.10  christos 	 is not smaller than uncompressed.  */
    612  1.10  christos       if (!update || compressed_size >= uncompressed_size)
    613   1.5  christos 	{
    614  1.10  christos 	  buffer_size = uncompressed_size;
    615  1.10  christos 	  buffer = bfd_malloc (buffer_size);
    616  1.10  christos 	  if (buffer == NULL)
    617  1.11  christos 	    return (bfd_size_type) -1;
    618  1.10  christos 
    619  1.10  christos 	  if (!decompress_contents (ch_type == ch_compress_zstd,
    620  1.10  christos 				    input_buffer + orig_header_size,
    621  1.10  christos 				    zlib_size, buffer, buffer_size))
    622  1.10  christos 	    {
    623  1.10  christos 	      bfd_set_error (bfd_error_bad_value);
    624  1.10  christos 	      free (buffer);
    625  1.11  christos 	      return (bfd_size_type) -1;
    626  1.10  christos 	    }
    627  1.10  christos 	  free (input_buffer);
    628  1.10  christos 	  bfd_set_section_alignment (sec, uncompressed_alignment_pow);
    629  1.10  christos 	  sec->contents = buffer;
    630  1.10  christos 	  sec->flags |= SEC_IN_MEMORY;
    631  1.10  christos 	  sec->compress_status = COMPRESS_SECTION_NONE;
    632  1.10  christos 	  sec->size = uncompressed_size;
    633  1.10  christos 	  input_buffer = buffer;
    634   1.5  christos 	}
    635  1.10  christos     }
    636  1.10  christos 
    637  1.10  christos   if (!update)
    638  1.10  christos     compressed_size = compressBound (uncompressed_size) + new_header_size;
    639   1.1  christos 
    640  1.10  christos   buffer_size = compressed_size;
    641  1.10  christos   buffer = bfd_alloc (abfd, buffer_size);
    642  1.10  christos   if (buffer == NULL)
    643  1.11  christos     return (bfd_size_type) -1;
    644   1.1  christos 
    645  1.10  christos   if (update)
    646   1.5  christos     {
    647  1.10  christos       if (compressed_size < uncompressed_size)
    648  1.10  christos 	memcpy (buffer + new_header_size,
    649  1.10  christos 		input_buffer + orig_header_size,
    650  1.10  christos 		zlib_size);
    651   1.5  christos     }
    652   1.5  christos   else
    653   1.5  christos     {
    654  1.10  christos       if (abfd->flags & BFD_COMPRESS_ZSTD)
    655   1.5  christos 	{
    656  1.10  christos #if HAVE_ZSTD
    657  1.10  christos 	  compressed_size = ZSTD_compress (buffer + new_header_size,
    658  1.10  christos 					   compressed_size,
    659  1.10  christos 					   input_buffer,
    660  1.10  christos 					   uncompressed_size,
    661  1.10  christos 					   ZSTD_CLEVEL_DEFAULT);
    662  1.10  christos 	  if (ZSTD_isError (compressed_size))
    663   1.5  christos 	    {
    664  1.10  christos 	      bfd_release (abfd, buffer);
    665   1.5  christos 	      bfd_set_error (bfd_error_bad_value);
    666  1.11  christos 	      return (bfd_size_type) -1;
    667   1.5  christos 	    }
    668  1.10  christos #endif
    669   1.5  christos 	}
    670  1.10  christos       else if (compress ((Bytef *) buffer + new_header_size, &compressed_size,
    671  1.10  christos 			 (const Bytef *) input_buffer, uncompressed_size)
    672  1.10  christos 	       != Z_OK)
    673   1.5  christos 	{
    674   1.5  christos 	  bfd_release (abfd, buffer);
    675   1.5  christos 	  bfd_set_error (bfd_error_bad_value);
    676  1.11  christos 	  return (bfd_size_type) -1;
    677   1.5  christos 	}
    678   1.1  christos 
    679  1.10  christos       compressed_size += new_header_size;
    680   1.5  christos     }
    681   1.1  christos 
    682  1.10  christos   /* If compression didn't make the section smaller, keep it uncompressed.  */
    683  1.10  christos   if (compressed_size >= uncompressed_size)
    684  1.10  christos     {
    685  1.10  christos       memcpy (buffer, input_buffer, uncompressed_size);
    686  1.10  christos       if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
    687  1.10  christos 	elf_section_flags (sec) &= ~SHF_COMPRESSED;
    688  1.10  christos       sec->compress_status = COMPRESS_SECTION_NONE;
    689  1.10  christos     }
    690  1.10  christos   else
    691  1.10  christos     {
    692  1.10  christos       sec->size = uncompressed_size;
    693  1.10  christos       bfd_update_compression_header (abfd, buffer, sec);
    694  1.10  christos       sec->size = compressed_size;
    695  1.10  christos       sec->compress_status = COMPRESS_SECTION_DONE;
    696  1.10  christos     }
    697   1.5  christos   sec->contents = buffer;
    698  1.10  christos   sec->flags |= SEC_IN_MEMORY;
    699  1.10  christos   free (input_buffer);
    700   1.5  christos   return uncompressed_size;
    701   1.1  christos }
    702   1.1  christos 
    703   1.1  christos /*
    704   1.1  christos FUNCTION
    705   1.1  christos 	bfd_get_full_section_contents
    706   1.1  christos 
    707   1.1  christos SYNOPSIS
    708  1.10  christos 	bool bfd_get_full_section_contents
    709   1.1  christos 	  (bfd *abfd, asection *section, bfd_byte **ptr);
    710   1.1  christos 
    711   1.1  christos DESCRIPTION
    712   1.1  christos 	Read all data from @var{section} in BFD @var{abfd}, decompress
    713   1.1  christos 	if needed, and store in @var{*ptr}.  If @var{*ptr} is NULL,
    714   1.1  christos 	return @var{*ptr} with memory malloc'd by this function.
    715   1.1  christos 
    716   1.1  christos 	Return @code{TRUE} if the full section contents is retrieved
    717   1.3  christos 	successfully.  If the section has no contents then this function
    718   1.3  christos 	returns @code{TRUE} but @var{*ptr} is set to NULL.
    719   1.1  christos */
    720   1.1  christos 
    721  1.10  christos bool
    722   1.1  christos bfd_get_full_section_contents (bfd *abfd, sec_ptr sec, bfd_byte **ptr)
    723   1.1  christos {
    724  1.10  christos   bfd_size_type readsz = bfd_get_section_limit_octets (abfd, sec);
    725  1.10  christos   bfd_size_type allocsz = bfd_get_section_alloc_size (abfd, sec);
    726   1.1  christos   bfd_byte *p = *ptr;
    727  1.10  christos   bool ret;
    728   1.1  christos   bfd_size_type save_size;
    729   1.1  christos   bfd_size_type save_rawsize;
    730   1.1  christos   bfd_byte *compressed_buffer;
    731   1.5  christos   unsigned int compression_header_size;
    732  1.10  christos   const unsigned int compress_status = sec->compress_status;
    733   1.1  christos 
    734  1.10  christos   if (allocsz == 0)
    735   1.3  christos     {
    736   1.3  christos       *ptr = NULL;
    737  1.10  christos       return true;
    738   1.3  christos     }
    739   1.1  christos 
    740  1.10  christos   if (p == NULL
    741  1.10  christos       && compress_status != COMPRESS_SECTION_DONE
    742  1.11  christos       && bfd_section_size_insane (abfd, sec))
    743  1.10  christos     {
    744  1.10  christos       /* PR 24708: Avoid attempts to allocate a ridiculous amount
    745  1.10  christos 	 of memory.  */
    746  1.10  christos       _bfd_error_handler
    747  1.10  christos 	/* xgettext:c-format */
    748  1.10  christos 	(_("error: %pB(%pA) is too large (%#" PRIx64 " bytes)"),
    749  1.10  christos 	 abfd, sec, (uint64_t) readsz);
    750  1.10  christos       return false;
    751  1.10  christos     }
    752  1.10  christos 
    753  1.10  christos   switch (compress_status)
    754   1.1  christos     {
    755   1.1  christos     case COMPRESS_SECTION_NONE:
    756  1.11  christos       if (p == NULL && !sec->mmapped_p)
    757   1.1  christos 	{
    758  1.10  christos 	  p = (bfd_byte *) bfd_malloc (allocsz);
    759   1.1  christos 	  if (p == NULL)
    760   1.7  christos 	    {
    761   1.7  christos 	      /* PR 20801: Provide a more helpful error message.  */
    762   1.7  christos 	      if (bfd_get_error () == bfd_error_no_memory)
    763   1.7  christos 		_bfd_error_handler
    764   1.7  christos 		  /* xgettext:c-format */
    765   1.8  christos 		  (_("error: %pB(%pA) is too large (%#" PRIx64 " bytes)"),
    766  1.10  christos 		  abfd, sec, (uint64_t) allocsz);
    767  1.10  christos 	      return false;
    768   1.7  christos 	    }
    769   1.1  christos 	}
    770   1.3  christos 
    771  1.10  christos       if (!bfd_get_section_contents (abfd, sec, p, 0, readsz))
    772   1.1  christos 	{
    773   1.1  christos 	  if (*ptr != p)
    774   1.1  christos 	    free (p);
    775  1.10  christos 	  return false;
    776   1.1  christos 	}
    777   1.1  christos       *ptr = p;
    778  1.10  christos       return true;
    779   1.1  christos 
    780  1.10  christos     case DECOMPRESS_SECTION_ZLIB:
    781  1.10  christos     case DECOMPRESS_SECTION_ZSTD:
    782   1.1  christos       /* Read in the full compressed section contents.  */
    783   1.1  christos       compressed_buffer = (bfd_byte *) bfd_malloc (sec->compressed_size);
    784   1.1  christos       if (compressed_buffer == NULL)
    785  1.10  christos 	return false;
    786   1.1  christos       save_rawsize = sec->rawsize;
    787   1.1  christos       save_size = sec->size;
    788   1.1  christos       /* Clear rawsize, set size to compressed size and set compress_status
    789   1.1  christos 	 to COMPRESS_SECTION_NONE.  If the compressed size is bigger than
    790   1.1  christos 	 the uncompressed size, bfd_get_section_contents will fail.  */
    791   1.1  christos       sec->rawsize = 0;
    792   1.1  christos       sec->size = sec->compressed_size;
    793   1.1  christos       sec->compress_status = COMPRESS_SECTION_NONE;
    794   1.1  christos       ret = bfd_get_section_contents (abfd, sec, compressed_buffer,
    795   1.1  christos 				      0, sec->compressed_size);
    796   1.1  christos       /* Restore rawsize and size.  */
    797   1.1  christos       sec->rawsize = save_rawsize;
    798   1.1  christos       sec->size = save_size;
    799  1.10  christos       sec->compress_status = compress_status;
    800   1.1  christos       if (!ret)
    801   1.1  christos 	goto fail_compressed;
    802   1.1  christos 
    803   1.1  christos       if (p == NULL)
    804  1.10  christos 	p = (bfd_byte *) bfd_malloc (allocsz);
    805   1.1  christos       if (p == NULL)
    806   1.1  christos 	goto fail_compressed;
    807   1.1  christos 
    808   1.5  christos       compression_header_size = bfd_get_compression_header_size (abfd, sec);
    809   1.5  christos       if (compression_header_size == 0)
    810   1.5  christos 	/* Set header size to the zlib header size if it is a
    811   1.5  christos 	   SHF_COMPRESSED section.  */
    812   1.5  christos 	compression_header_size = 12;
    813  1.10  christos       bool is_zstd = compress_status == DECOMPRESS_SECTION_ZSTD;
    814  1.10  christos       if (!decompress_contents (
    815  1.10  christos 	      is_zstd, compressed_buffer + compression_header_size,
    816  1.10  christos 	      sec->compressed_size - compression_header_size, p, readsz))
    817   1.1  christos 	{
    818   1.1  christos 	  bfd_set_error (bfd_error_bad_value);
    819   1.1  christos 	  if (p != *ptr)
    820   1.1  christos 	    free (p);
    821   1.1  christos 	fail_compressed:
    822   1.1  christos 	  free (compressed_buffer);
    823  1.10  christos 	  return false;
    824   1.1  christos 	}
    825   1.1  christos 
    826   1.1  christos       free (compressed_buffer);
    827   1.1  christos       *ptr = p;
    828  1.10  christos       return true;
    829   1.1  christos 
    830   1.1  christos     case COMPRESS_SECTION_DONE:
    831   1.3  christos       if (sec->contents == NULL)
    832  1.10  christos 	return false;
    833   1.1  christos       if (p == NULL)
    834   1.1  christos 	{
    835  1.10  christos 	  p = (bfd_byte *) bfd_malloc (allocsz);
    836   1.1  christos 	  if (p == NULL)
    837  1.10  christos 	    return false;
    838   1.1  christos 	  *ptr = p;
    839   1.1  christos 	}
    840   1.3  christos       /* PR 17512; file: 5bc29788.  */
    841   1.3  christos       if (p != sec->contents)
    842  1.10  christos 	memcpy (p, sec->contents, readsz);
    843  1.10  christos       return true;
    844   1.1  christos 
    845   1.1  christos     default:
    846   1.1  christos       abort ();
    847   1.1  christos     }
    848   1.1  christos }
    849   1.1  christos 
    850   1.1  christos /*
    851   1.1  christos FUNCTION
    852  1.10  christos 	bfd_is_section_compressed_info
    853   1.1  christos 
    854   1.1  christos SYNOPSIS
    855  1.10  christos 	bool bfd_is_section_compressed_info
    856   1.5  christos 	  (bfd *abfd, asection *section,
    857  1.10  christos 	   int *compression_header_size_p,
    858  1.10  christos 	   bfd_size_type *uncompressed_size_p,
    859  1.10  christos 	   unsigned int *uncompressed_alignment_power_p,
    860  1.10  christos 	   enum compression_type *ch_type);
    861   1.1  christos 
    862   1.1  christos DESCRIPTION
    863   1.5  christos 	Return @code{TRUE} if @var{section} is compressed.  Compression
    864   1.8  christos 	header size is returned in @var{compression_header_size_p},
    865   1.8  christos 	uncompressed size is returned in @var{uncompressed_size_p}
    866   1.8  christos 	and the uncompressed data alignement power is returned in
    867   1.8  christos 	@var{uncompressed_align_pow_p}.  If compression is
    868   1.8  christos 	unsupported, compression header size is returned with -1
    869   1.8  christos 	and uncompressed size is returned with 0.
    870   1.1  christos */
    871   1.1  christos 
    872  1.10  christos bool
    873  1.10  christos bfd_is_section_compressed_info (bfd *abfd, sec_ptr sec,
    874  1.10  christos 				int *compression_header_size_p,
    875  1.10  christos 				bfd_size_type *uncompressed_size_p,
    876  1.10  christos 				unsigned int *uncompressed_align_pow_p,
    877  1.10  christos 				enum compression_type *ch_type)
    878   1.1  christos {
    879   1.5  christos   bfd_byte header[MAX_COMPRESSION_HEADER_SIZE];
    880   1.5  christos   int compression_header_size;
    881   1.5  christos   int header_size;
    882   1.1  christos   unsigned int saved = sec->compress_status;
    883  1.10  christos   bool compressed;
    884   1.1  christos 
    885   1.8  christos   *uncompressed_align_pow_p = 0;
    886   1.8  christos 
    887   1.5  christos   compression_header_size = bfd_get_compression_header_size (abfd, sec);
    888   1.5  christos   if (compression_header_size > MAX_COMPRESSION_HEADER_SIZE)
    889   1.5  christos     abort ();
    890   1.5  christos   header_size = compression_header_size ? compression_header_size : 12;
    891   1.5  christos 
    892   1.1  christos   /* Don't decompress the section.  */
    893   1.1  christos   sec->compress_status = COMPRESS_SECTION_NONE;
    894   1.1  christos 
    895   1.5  christos   /* Read the header.  */
    896   1.5  christos   if (bfd_get_section_contents (abfd, sec, header, 0, header_size))
    897   1.5  christos     {
    898   1.5  christos       if (compression_header_size == 0)
    899   1.8  christos 	/* In this case, it should be "ZLIB" followed by the uncompressed
    900   1.5  christos 	   section size, 8 bytes in big-endian order.  */
    901  1.10  christos 	compressed = startswith ((char*) header , "ZLIB");
    902   1.5  christos       else
    903  1.10  christos 	compressed = true;
    904   1.5  christos     }
    905   1.5  christos   else
    906  1.10  christos     compressed = false;
    907   1.3  christos 
    908   1.5  christos   *uncompressed_size_p = sec->size;
    909   1.5  christos   if (compressed)
    910   1.5  christos     {
    911   1.5  christos       if (compression_header_size != 0)
    912   1.5  christos 	{
    913  1.10  christos 	  if (!bfd_check_compression_header (abfd, header, sec, ch_type,
    914   1.8  christos 					     uncompressed_size_p,
    915   1.8  christos 					     uncompressed_align_pow_p))
    916   1.5  christos 	    compression_header_size = -1;
    917   1.5  christos 	}
    918   1.5  christos       /* Check for the pathalogical case of a debug string section that
    919   1.5  christos 	 contains the string ZLIB.... as the first entry.  We assume that
    920   1.5  christos 	 no uncompressed .debug_str section would ever be big enough to
    921   1.5  christos 	 have the first byte of its (big-endian) size be non-zero.  */
    922   1.5  christos       else if (strcmp (sec->name, ".debug_str") == 0
    923   1.5  christos 	       && ISPRINT (header[4]))
    924  1.10  christos 	compressed = false;
    925   1.5  christos       else
    926   1.5  christos 	*uncompressed_size_p = bfd_getb64 (header + 4);
    927   1.5  christos     }
    928   1.5  christos 
    929   1.1  christos   /* Restore compress_status.  */
    930   1.1  christos   sec->compress_status = saved;
    931   1.5  christos   *compression_header_size_p = compression_header_size;
    932   1.1  christos   return compressed;
    933   1.1  christos }
    934   1.1  christos 
    935   1.1  christos /*
    936   1.1  christos FUNCTION
    937   1.5  christos 	bfd_is_section_compressed
    938   1.5  christos 
    939   1.5  christos SYNOPSIS
    940  1.10  christos 	bool bfd_is_section_compressed
    941   1.5  christos 	  (bfd *abfd, asection *section);
    942   1.5  christos 
    943   1.5  christos DESCRIPTION
    944   1.5  christos 	Return @code{TRUE} if @var{section} is compressed.
    945   1.5  christos */
    946   1.5  christos 
    947  1.10  christos bool
    948   1.5  christos bfd_is_section_compressed (bfd *abfd, sec_ptr sec)
    949   1.5  christos {
    950   1.5  christos   int compression_header_size;
    951   1.5  christos   bfd_size_type uncompressed_size;
    952   1.8  christos   unsigned int uncompressed_align_power;
    953  1.10  christos   enum compression_type ch_type;
    954  1.10  christos   return (bfd_is_section_compressed_info (abfd, sec,
    955  1.10  christos 					  &compression_header_size,
    956  1.10  christos 					  &uncompressed_size,
    957  1.10  christos 					  &uncompressed_align_power,
    958  1.10  christos 					  &ch_type)
    959   1.5  christos 	  && compression_header_size >= 0
    960   1.5  christos 	  && uncompressed_size > 0);
    961   1.5  christos }
    962   1.5  christos 
    963   1.5  christos /*
    964   1.5  christos FUNCTION
    965   1.1  christos 	bfd_init_section_decompress_status
    966   1.1  christos 
    967   1.1  christos SYNOPSIS
    968  1.10  christos 	bool bfd_init_section_decompress_status
    969   1.1  christos 	  (bfd *abfd, asection *section);
    970   1.1  christos 
    971   1.1  christos DESCRIPTION
    972   1.1  christos 	Record compressed section size, update section size with
    973   1.1  christos 	decompressed size and set compress_status to
    974  1.10  christos 	DECOMPRESS_SECTION_{ZLIB,ZSTD}.
    975   1.1  christos 
    976   1.1  christos 	Return @code{FALSE} if the section is not a valid compressed
    977   1.5  christos 	section.  Otherwise, return @code{TRUE}.
    978   1.1  christos */
    979   1.1  christos 
    980  1.10  christos bool
    981   1.5  christos bfd_init_section_decompress_status (bfd *abfd, sec_ptr sec)
    982   1.1  christos {
    983   1.5  christos   bfd_byte header[MAX_COMPRESSION_HEADER_SIZE];
    984   1.5  christos   int compression_header_size;
    985   1.5  christos   int header_size;
    986   1.1  christos   bfd_size_type uncompressed_size;
    987   1.8  christos   unsigned int uncompressed_alignment_power = 0;
    988  1.10  christos   enum compression_type ch_type;
    989  1.10  christos   z_stream strm;
    990   1.1  christos 
    991   1.5  christos   compression_header_size = bfd_get_compression_header_size (abfd, sec);
    992   1.5  christos   if (compression_header_size > MAX_COMPRESSION_HEADER_SIZE)
    993   1.5  christos     abort ();
    994   1.5  christos   header_size = compression_header_size ? compression_header_size : 12;
    995   1.5  christos 
    996   1.5  christos   /* Read the header.  */
    997   1.1  christos   if (sec->rawsize != 0
    998   1.1  christos       || sec->contents != NULL
    999   1.1  christos       || sec->compress_status != COMPRESS_SECTION_NONE
   1000   1.5  christos       || !bfd_get_section_contents (abfd, sec, header, 0, header_size))
   1001   1.1  christos     {
   1002   1.1  christos       bfd_set_error (bfd_error_invalid_operation);
   1003  1.10  christos       return false;
   1004   1.1  christos     }
   1005   1.1  christos 
   1006   1.5  christos   if (compression_header_size == 0)
   1007   1.5  christos     {
   1008   1.5  christos       /* In this case, it should be "ZLIB" followed by the uncompressed
   1009   1.5  christos 	 section size, 8 bytes in big-endian order.  */
   1010  1.10  christos       if (! startswith ((char*) header, "ZLIB"))
   1011   1.5  christos 	{
   1012   1.5  christos 	  bfd_set_error (bfd_error_wrong_format);
   1013  1.10  christos 	  return false;
   1014   1.5  christos 	}
   1015   1.5  christos       uncompressed_size = bfd_getb64 (header + 4);
   1016  1.10  christos       ch_type = ch_none;
   1017   1.5  christos     }
   1018   1.5  christos   else if (!bfd_check_compression_header (abfd, header, sec,
   1019  1.10  christos 					  &ch_type,
   1020   1.8  christos 					  &uncompressed_size,
   1021   1.8  christos 					  &uncompressed_alignment_power))
   1022   1.1  christos     {
   1023   1.1  christos       bfd_set_error (bfd_error_wrong_format);
   1024  1.10  christos       return false;
   1025  1.10  christos     }
   1026  1.10  christos 
   1027  1.10  christos   /* PR28530, reject sizes unsupported by decompress_contents.  */
   1028  1.10  christos   strm.avail_in = sec->size;
   1029  1.10  christos   strm.avail_out = uncompressed_size;
   1030  1.10  christos   if (strm.avail_in != sec->size || strm.avail_out != uncompressed_size)
   1031  1.10  christos     {
   1032  1.10  christos       bfd_set_error (bfd_error_nonrepresentable_section);
   1033  1.10  christos       return false;
   1034   1.1  christos     }
   1035   1.1  christos 
   1036   1.1  christos   sec->compressed_size = sec->size;
   1037   1.1  christos   sec->size = uncompressed_size;
   1038   1.9  christos   bfd_set_section_alignment (sec, uncompressed_alignment_power);
   1039  1.10  christos   sec->compress_status = (ch_type == ch_compress_zstd
   1040  1.10  christos 			  ? DECOMPRESS_SECTION_ZSTD : DECOMPRESS_SECTION_ZLIB);
   1041   1.1  christos 
   1042  1.10  christos   return true;
   1043   1.1  christos }
   1044   1.1  christos 
   1045   1.1  christos /*
   1046   1.1  christos FUNCTION
   1047   1.1  christos 	bfd_init_section_compress_status
   1048   1.1  christos 
   1049   1.1  christos SYNOPSIS
   1050  1.10  christos 	bool bfd_init_section_compress_status
   1051   1.1  christos 	  (bfd *abfd, asection *section);
   1052   1.1  christos 
   1053   1.1  christos DESCRIPTION
   1054   1.1  christos 	If open for read, compress section, update section size with
   1055   1.1  christos 	compressed size and set compress_status to COMPRESS_SECTION_DONE.
   1056   1.1  christos 
   1057   1.1  christos 	Return @code{FALSE} if the section is not a valid compressed
   1058   1.5  christos 	section.  Otherwise, return @code{TRUE}.
   1059   1.1  christos */
   1060   1.1  christos 
   1061  1.10  christos bool
   1062   1.5  christos bfd_init_section_compress_status (bfd *abfd, sec_ptr sec)
   1063   1.1  christos {
   1064   1.1  christos   bfd_size_type uncompressed_size;
   1065   1.1  christos   bfd_byte *uncompressed_buffer;
   1066   1.1  christos 
   1067   1.1  christos   /* Error if not opened for read.  */
   1068   1.1  christos   if (abfd->direction != read_direction
   1069   1.1  christos       || sec->size == 0
   1070   1.1  christos       || sec->rawsize != 0
   1071   1.1  christos       || sec->contents != NULL
   1072  1.11  christos       || sec->compress_status != COMPRESS_SECTION_NONE
   1073  1.11  christos       || bfd_section_size_insane (abfd, sec))
   1074   1.1  christos     {
   1075   1.1  christos       bfd_set_error (bfd_error_invalid_operation);
   1076  1.10  christos       return false;
   1077   1.1  christos     }
   1078   1.1  christos 
   1079   1.1  christos   /* Read in the full section contents and compress it.  */
   1080   1.1  christos   uncompressed_size = sec->size;
   1081   1.1  christos   uncompressed_buffer = (bfd_byte *) bfd_malloc (uncompressed_size);
   1082   1.8  christos   /* PR 21431 */
   1083   1.8  christos   if (uncompressed_buffer == NULL)
   1084  1.10  christos     return false;
   1085   1.8  christos 
   1086   1.1  christos   if (!bfd_get_section_contents (abfd, sec, uncompressed_buffer,
   1087   1.1  christos 				 0, uncompressed_size))
   1088  1.11  christos     {
   1089  1.11  christos       free (uncompressed_buffer);
   1090  1.11  christos       return false;
   1091  1.11  christos     }
   1092   1.1  christos 
   1093  1.10  christos   sec->contents = uncompressed_buffer;
   1094  1.11  christos   if (bfd_compress_section_contents (abfd, sec) == (bfd_size_type) -1)
   1095  1.10  christos     {
   1096  1.10  christos       free (sec->contents);
   1097  1.10  christos       sec->contents = NULL;
   1098  1.10  christos       return false;
   1099  1.10  christos     }
   1100  1.10  christos   return true;
   1101   1.5  christos }
   1102   1.5  christos 
   1103   1.5  christos /*
   1104   1.5  christos FUNCTION
   1105   1.5  christos 	bfd_compress_section
   1106   1.5  christos 
   1107   1.5  christos SYNOPSIS
   1108  1.10  christos 	bool bfd_compress_section
   1109   1.5  christos 	  (bfd *abfd, asection *section, bfd_byte *uncompressed_buffer);
   1110   1.5  christos 
   1111   1.5  christos DESCRIPTION
   1112   1.5  christos 	If open for write, compress section, update section size with
   1113   1.5  christos 	compressed size and set compress_status to COMPRESS_SECTION_DONE.
   1114   1.5  christos 
   1115   1.5  christos 	Return @code{FALSE} if compression fail.  Otherwise, return
   1116  1.10  christos 	@code{TRUE}.  UNCOMPRESSED_BUFFER is freed in both cases.
   1117   1.5  christos */
   1118   1.5  christos 
   1119  1.10  christos bool
   1120   1.5  christos bfd_compress_section (bfd *abfd, sec_ptr sec, bfd_byte *uncompressed_buffer)
   1121   1.5  christos {
   1122   1.5  christos   bfd_size_type uncompressed_size = sec->size;
   1123   1.5  christos 
   1124   1.5  christos   /* Error if not opened for write.  */
   1125   1.5  christos   if (abfd->direction != write_direction
   1126   1.5  christos       || uncompressed_size == 0
   1127   1.5  christos       || uncompressed_buffer == NULL
   1128   1.5  christos       || sec->contents != NULL
   1129   1.5  christos       || sec->compressed_size != 0
   1130   1.5  christos       || sec->compress_status != COMPRESS_SECTION_NONE)
   1131   1.5  christos     {
   1132   1.5  christos       bfd_set_error (bfd_error_invalid_operation);
   1133  1.10  christos       return false;
   1134   1.5  christos     }
   1135   1.5  christos 
   1136  1.10  christos   sec->contents = uncompressed_buffer;
   1137  1.11  christos   if (bfd_compress_section_contents (abfd, sec) == (bfd_size_type) -1)
   1138  1.10  christos     {
   1139  1.10  christos       free (sec->contents);
   1140  1.10  christos       sec->contents = NULL;
   1141  1.10  christos       return false;
   1142  1.10  christos     }
   1143  1.10  christos   return true;
   1144   1.1  christos }
   1145