Home | History | Annotate | Line # | Download | only in bfd
compress.c revision 1.7
      1  1.1  christos /* Compressed section support (intended for debug sections).
      2  1.7  christos    Copyright (C) 2008-2017 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.1  christos #include "bfd.h"
     24  1.1  christos #include "libbfd.h"
     25  1.3  christos #include "safe-ctype.h"
     26  1.1  christos 
     27  1.5  christos #define MAX_COMPRESSION_HEADER_SIZE 24
     28  1.5  christos 
     29  1.1  christos static bfd_boolean
     30  1.1  christos decompress_contents (bfd_byte *compressed_buffer,
     31  1.1  christos 		     bfd_size_type compressed_size,
     32  1.1  christos 		     bfd_byte *uncompressed_buffer,
     33  1.1  christos 		     bfd_size_type uncompressed_size)
     34  1.1  christos {
     35  1.1  christos   z_stream strm;
     36  1.1  christos   int rc;
     37  1.1  christos 
     38  1.1  christos   /* It is possible the section consists of several compressed
     39  1.1  christos      buffers concatenated together, so we uncompress in a loop.  */
     40  1.5  christos   /* PR 18313: The state field in the z_stream structure is supposed
     41  1.5  christos      to be invisible to the user (ie us), but some compilers will
     42  1.5  christos      still complain about it being used without initialisation.  So
     43  1.5  christos      we first zero the entire z_stream structure and then set the fields
     44  1.5  christos      that we need.  */
     45  1.5  christos   memset (& strm, 0, sizeof strm);
     46  1.5  christos   strm.avail_in = compressed_size;
     47  1.5  christos   strm.next_in = (Bytef*) compressed_buffer;
     48  1.1  christos   strm.avail_out = uncompressed_size;
     49  1.1  christos 
     50  1.1  christos   BFD_ASSERT (Z_OK == 0);
     51  1.1  christos   rc = inflateInit (&strm);
     52  1.1  christos   while (strm.avail_in > 0 && strm.avail_out > 0)
     53  1.1  christos     {
     54  1.1  christos       if (rc != Z_OK)
     55  1.1  christos 	break;
     56  1.1  christos       strm.next_out = ((Bytef*) uncompressed_buffer
     57  1.1  christos                        + (uncompressed_size - strm.avail_out));
     58  1.1  christos       rc = inflate (&strm, Z_FINISH);
     59  1.1  christos       if (rc != Z_STREAM_END)
     60  1.1  christos 	break;
     61  1.1  christos       rc = inflateReset (&strm);
     62  1.1  christos     }
     63  1.1  christos   rc |= inflateEnd (&strm);
     64  1.1  christos   return rc == Z_OK && strm.avail_out == 0;
     65  1.1  christos }
     66  1.1  christos 
     67  1.5  christos /* Compress data of the size specified in @var{uncompressed_size}
     68  1.5  christos    and pointed to by @var{uncompressed_buffer} using zlib and store
     69  1.5  christos    as the contents field.  This function assumes the contents
     70  1.5  christos    field was allocated using bfd_malloc() or equivalent.
     71  1.5  christos 
     72  1.5  christos    Return the uncompressed size if the full section contents is
     73  1.5  christos    compressed successfully.  Otherwise return 0.  */
     74  1.5  christos 
     75  1.5  christos static bfd_size_type
     76  1.5  christos bfd_compress_section_contents (bfd *abfd, sec_ptr sec,
     77  1.5  christos 			       bfd_byte *uncompressed_buffer,
     78  1.5  christos 			       bfd_size_type uncompressed_size)
     79  1.1  christos {
     80  1.1  christos   uLong compressed_size;
     81  1.5  christos   bfd_byte *buffer;
     82  1.5  christos   bfd_size_type buffer_size;
     83  1.5  christos   bfd_boolean decompress;
     84  1.5  christos   int zlib_size = 0;
     85  1.5  christos   int orig_compression_header_size;
     86  1.5  christos   bfd_size_type orig_uncompressed_size;
     87  1.5  christos   int header_size = bfd_get_compression_header_size (abfd, NULL);
     88  1.5  christos   bfd_boolean compressed
     89  1.5  christos     = bfd_is_section_compressed_with_header (abfd, sec,
     90  1.5  christos 					     &orig_compression_header_size,
     91  1.5  christos 					     &orig_uncompressed_size);
     92  1.5  christos 
     93  1.5  christos   /* Either ELF compression header or the 12-byte, "ZLIB" + 8-byte size,
     94  1.5  christos      overhead in .zdebug* section.  */
     95  1.5  christos   if (!header_size)
     96  1.5  christos      header_size = 12;
     97  1.5  christos 
     98  1.5  christos   if (compressed)
     99  1.5  christos     {
    100  1.5  christos       /* We shouldn't decompress unsupported compressed section.  */
    101  1.5  christos       if (orig_compression_header_size < 0)
    102  1.5  christos 	abort ();
    103  1.5  christos 
    104  1.5  christos       /* Different compression schemes.  Just move the compressed section
    105  1.5  christos 	 contents to the right position. */
    106  1.5  christos       if (orig_compression_header_size == 0)
    107  1.5  christos 	{
    108  1.5  christos 	  /* Convert it from .zdebug* section.  Get the uncompressed
    109  1.5  christos 	     size first.  We need to substract the 12-byte overhead in
    110  1.5  christos 	     .zdebug* section.  Set orig_compression_header_size to
    111  1.5  christos 	     the 12-bye overhead.  */
    112  1.5  christos 	  orig_compression_header_size = 12;
    113  1.5  christos 	  zlib_size = uncompressed_size - 12;
    114  1.5  christos 	}
    115  1.5  christos       else
    116  1.5  christos 	{
    117  1.5  christos 	  /* Convert it to .zdebug* section.  */
    118  1.5  christos 	  zlib_size = uncompressed_size - orig_compression_header_size;
    119  1.5  christos 	}
    120  1.1  christos 
    121  1.5  christos       /* Add the header size.  */
    122  1.5  christos       compressed_size = zlib_size + header_size;
    123  1.5  christos     }
    124  1.5  christos   else
    125  1.5  christos     compressed_size = compressBound (uncompressed_size) + header_size;
    126  1.1  christos 
    127  1.5  christos   /* Uncompress if it leads to smaller size.  */
    128  1.5  christos   if (compressed && compressed_size > orig_uncompressed_size)
    129  1.5  christos     {
    130  1.5  christos       decompress = TRUE;
    131  1.5  christos       buffer_size = orig_uncompressed_size;
    132  1.5  christos     }
    133  1.5  christos   else
    134  1.5  christos     {
    135  1.5  christos       decompress = FALSE;
    136  1.5  christos       buffer_size = compressed_size;
    137  1.5  christos     }
    138  1.5  christos   buffer = (bfd_byte *) bfd_alloc (abfd, buffer_size);
    139  1.5  christos   if (buffer == NULL)
    140  1.5  christos     return 0;
    141  1.1  christos 
    142  1.5  christos   if (compressed)
    143  1.1  christos     {
    144  1.5  christos       sec->size = orig_uncompressed_size;
    145  1.5  christos       if (decompress)
    146  1.5  christos 	{
    147  1.5  christos 	  if (!decompress_contents (uncompressed_buffer
    148  1.5  christos 				    + orig_compression_header_size,
    149  1.5  christos 				    zlib_size, buffer, buffer_size))
    150  1.5  christos 	    {
    151  1.5  christos 	      bfd_set_error (bfd_error_bad_value);
    152  1.5  christos 	      bfd_release (abfd, buffer);
    153  1.5  christos 	      return 0;
    154  1.5  christos 	    }
    155  1.5  christos 	  free (uncompressed_buffer);
    156  1.5  christos 	  sec->contents = buffer;
    157  1.5  christos 	  sec->compress_status = COMPRESS_SECTION_DONE;
    158  1.5  christos 	  return orig_uncompressed_size;
    159  1.5  christos 	}
    160  1.5  christos       else
    161  1.5  christos 	{
    162  1.5  christos 	  bfd_update_compression_header (abfd, buffer, sec);
    163  1.5  christos 	  memmove (buffer + header_size,
    164  1.5  christos 		   uncompressed_buffer + orig_compression_header_size,
    165  1.5  christos 		   zlib_size);
    166  1.5  christos 	}
    167  1.1  christos     }
    168  1.5  christos   else
    169  1.5  christos     {
    170  1.5  christos       if (compress ((Bytef*) buffer + header_size,
    171  1.5  christos 		    &compressed_size,
    172  1.5  christos 		    (const Bytef*) uncompressed_buffer,
    173  1.5  christos 		    uncompressed_size) != Z_OK)
    174  1.5  christos 	{
    175  1.5  christos 	  bfd_release (abfd, buffer);
    176  1.5  christos 	  bfd_set_error (bfd_error_bad_value);
    177  1.5  christos 	  return 0;
    178  1.5  christos 	}
    179  1.1  christos 
    180  1.5  christos       compressed_size += header_size;
    181  1.5  christos       /* PR binutils/18087: If compression didn't make the section smaller,
    182  1.5  christos 	 just keep it uncompressed.  */
    183  1.5  christos       if (compressed_size < uncompressed_size)
    184  1.5  christos 	bfd_update_compression_header (abfd, buffer, sec);
    185  1.5  christos       else
    186  1.5  christos 	{
    187  1.5  christos 	  /* NOTE: There is a small memory leak here since
    188  1.5  christos 	     uncompressed_buffer is malloced and won't be freed.  */
    189  1.5  christos 	  bfd_release (abfd, buffer);
    190  1.5  christos 	  sec->contents = uncompressed_buffer;
    191  1.5  christos 	  sec->compress_status = COMPRESS_SECTION_NONE;
    192  1.5  christos 	  return uncompressed_size;
    193  1.5  christos 	}
    194  1.5  christos     }
    195  1.1  christos 
    196  1.5  christos   free (uncompressed_buffer);
    197  1.5  christos   sec->contents = buffer;
    198  1.1  christos   sec->size = compressed_size;
    199  1.1  christos   sec->compress_status = COMPRESS_SECTION_DONE;
    200  1.1  christos 
    201  1.5  christos   return uncompressed_size;
    202  1.1  christos }
    203  1.1  christos 
    204  1.1  christos /*
    205  1.1  christos FUNCTION
    206  1.1  christos 	bfd_get_full_section_contents
    207  1.1  christos 
    208  1.1  christos SYNOPSIS
    209  1.1  christos 	bfd_boolean bfd_get_full_section_contents
    210  1.1  christos 	  (bfd *abfd, asection *section, bfd_byte **ptr);
    211  1.1  christos 
    212  1.1  christos DESCRIPTION
    213  1.1  christos 	Read all data from @var{section} in BFD @var{abfd}, decompress
    214  1.1  christos 	if needed, and store in @var{*ptr}.  If @var{*ptr} is NULL,
    215  1.1  christos 	return @var{*ptr} with memory malloc'd by this function.
    216  1.1  christos 
    217  1.1  christos 	Return @code{TRUE} if the full section contents is retrieved
    218  1.3  christos 	successfully.  If the section has no contents then this function
    219  1.3  christos 	returns @code{TRUE} but @var{*ptr} is set to NULL.
    220  1.1  christos */
    221  1.1  christos 
    222  1.1  christos bfd_boolean
    223  1.1  christos bfd_get_full_section_contents (bfd *abfd, sec_ptr sec, bfd_byte **ptr)
    224  1.1  christos {
    225  1.1  christos   bfd_size_type sz;
    226  1.1  christos   bfd_byte *p = *ptr;
    227  1.1  christos   bfd_boolean ret;
    228  1.1  christos   bfd_size_type save_size;
    229  1.1  christos   bfd_size_type save_rawsize;
    230  1.1  christos   bfd_byte *compressed_buffer;
    231  1.5  christos   unsigned int compression_header_size;
    232  1.1  christos 
    233  1.1  christos   if (abfd->direction != write_direction && sec->rawsize != 0)
    234  1.1  christos     sz = sec->rawsize;
    235  1.1  christos   else
    236  1.1  christos     sz = sec->size;
    237  1.1  christos   if (sz == 0)
    238  1.3  christos     {
    239  1.3  christos       *ptr = NULL;
    240  1.3  christos       return TRUE;
    241  1.3  christos     }
    242  1.1  christos 
    243  1.1  christos   switch (sec->compress_status)
    244  1.1  christos     {
    245  1.1  christos     case COMPRESS_SECTION_NONE:
    246  1.1  christos       if (p == NULL)
    247  1.1  christos 	{
    248  1.1  christos 	  p = (bfd_byte *) bfd_malloc (sz);
    249  1.1  christos 	  if (p == NULL)
    250  1.7  christos 	    {
    251  1.7  christos 	      /* PR 20801: Provide a more helpful error message.  */
    252  1.7  christos 	      if (bfd_get_error () == bfd_error_no_memory)
    253  1.7  christos 		_bfd_error_handler
    254  1.7  christos 		  /* xgettext:c-format */
    255  1.7  christos 		  (_("error: %B(%A) is too large (%#lx bytes)"),
    256  1.7  christos 		  abfd, sec, (long) sz);
    257  1.1  christos 	    return FALSE;
    258  1.7  christos 	    }
    259  1.1  christos 	}
    260  1.3  christos 
    261  1.1  christos       if (!bfd_get_section_contents (abfd, sec, p, 0, sz))
    262  1.1  christos 	{
    263  1.1  christos 	  if (*ptr != p)
    264  1.1  christos 	    free (p);
    265  1.1  christos 	  return FALSE;
    266  1.1  christos 	}
    267  1.1  christos       *ptr = p;
    268  1.1  christos       return TRUE;
    269  1.1  christos 
    270  1.1  christos     case DECOMPRESS_SECTION_SIZED:
    271  1.1  christos       /* Read in the full compressed section contents.  */
    272  1.1  christos       compressed_buffer = (bfd_byte *) bfd_malloc (sec->compressed_size);
    273  1.1  christos       if (compressed_buffer == NULL)
    274  1.1  christos 	return FALSE;
    275  1.1  christos       save_rawsize = sec->rawsize;
    276  1.1  christos       save_size = sec->size;
    277  1.1  christos       /* Clear rawsize, set size to compressed size and set compress_status
    278  1.1  christos 	 to COMPRESS_SECTION_NONE.  If the compressed size is bigger than
    279  1.1  christos 	 the uncompressed size, bfd_get_section_contents will fail.  */
    280  1.1  christos       sec->rawsize = 0;
    281  1.1  christos       sec->size = sec->compressed_size;
    282  1.1  christos       sec->compress_status = COMPRESS_SECTION_NONE;
    283  1.1  christos       ret = bfd_get_section_contents (abfd, sec, compressed_buffer,
    284  1.1  christos 				      0, sec->compressed_size);
    285  1.1  christos       /* Restore rawsize and size.  */
    286  1.1  christos       sec->rawsize = save_rawsize;
    287  1.1  christos       sec->size = save_size;
    288  1.1  christos       sec->compress_status = DECOMPRESS_SECTION_SIZED;
    289  1.1  christos       if (!ret)
    290  1.1  christos 	goto fail_compressed;
    291  1.1  christos 
    292  1.1  christos       if (p == NULL)
    293  1.1  christos 	p = (bfd_byte *) bfd_malloc (sz);
    294  1.1  christos       if (p == NULL)
    295  1.1  christos 	goto fail_compressed;
    296  1.1  christos 
    297  1.5  christos       compression_header_size = bfd_get_compression_header_size (abfd, sec);
    298  1.5  christos       if (compression_header_size == 0)
    299  1.5  christos 	/* Set header size to the zlib header size if it is a
    300  1.5  christos 	   SHF_COMPRESSED section.  */
    301  1.5  christos 	compression_header_size = 12;
    302  1.5  christos       if (!decompress_contents (compressed_buffer + compression_header_size,
    303  1.7  christos 				sec->compressed_size - compression_header_size, p, sz))
    304  1.1  christos 	{
    305  1.1  christos 	  bfd_set_error (bfd_error_bad_value);
    306  1.1  christos 	  if (p != *ptr)
    307  1.1  christos 	    free (p);
    308  1.1  christos 	fail_compressed:
    309  1.1  christos 	  free (compressed_buffer);
    310  1.1  christos 	  return FALSE;
    311  1.1  christos 	}
    312  1.1  christos 
    313  1.1  christos       free (compressed_buffer);
    314  1.1  christos       *ptr = p;
    315  1.1  christos       return TRUE;
    316  1.1  christos 
    317  1.1  christos     case COMPRESS_SECTION_DONE:
    318  1.3  christos       if (sec->contents == NULL)
    319  1.3  christos 	return FALSE;
    320  1.1  christos       if (p == NULL)
    321  1.1  christos 	{
    322  1.1  christos 	  p = (bfd_byte *) bfd_malloc (sz);
    323  1.1  christos 	  if (p == NULL)
    324  1.1  christos 	    return FALSE;
    325  1.1  christos 	  *ptr = p;
    326  1.1  christos 	}
    327  1.3  christos       /* PR 17512; file: 5bc29788.  */
    328  1.3  christos       if (p != sec->contents)
    329  1.3  christos 	memcpy (p, sec->contents, sz);
    330  1.1  christos       return TRUE;
    331  1.1  christos 
    332  1.1  christos     default:
    333  1.1  christos       abort ();
    334  1.1  christos     }
    335  1.1  christos }
    336  1.1  christos 
    337  1.1  christos /*
    338  1.1  christos FUNCTION
    339  1.1  christos 	bfd_cache_section_contents
    340  1.1  christos 
    341  1.1  christos SYNOPSIS
    342  1.1  christos 	void bfd_cache_section_contents
    343  1.1  christos 	  (asection *sec, void *contents);
    344  1.1  christos 
    345  1.1  christos DESCRIPTION
    346  1.1  christos 	Stash @var(contents) so any following reads of @var(sec) do
    347  1.1  christos 	not need to decompress again.
    348  1.1  christos */
    349  1.1  christos 
    350  1.1  christos void
    351  1.1  christos bfd_cache_section_contents (asection *sec, void *contents)
    352  1.1  christos {
    353  1.1  christos   if (sec->compress_status == DECOMPRESS_SECTION_SIZED)
    354  1.1  christos     sec->compress_status = COMPRESS_SECTION_DONE;
    355  1.1  christos   sec->contents = contents;
    356  1.1  christos   sec->flags |= SEC_IN_MEMORY;
    357  1.1  christos }
    358  1.1  christos 
    359  1.1  christos /*
    360  1.1  christos FUNCTION
    361  1.5  christos 	bfd_is_section_compressed_with_header
    362  1.1  christos 
    363  1.1  christos SYNOPSIS
    364  1.5  christos 	bfd_boolean bfd_is_section_compressed_with_header
    365  1.5  christos 	  (bfd *abfd, asection *section,
    366  1.5  christos 	  int *compression_header_size_p,
    367  1.5  christos 	  bfd_size_type *uncompressed_size_p);
    368  1.1  christos 
    369  1.1  christos DESCRIPTION
    370  1.5  christos 	Return @code{TRUE} if @var{section} is compressed.  Compression
    371  1.5  christos 	header size is returned in @var{compression_header_size_p} and
    372  1.5  christos 	uncompressed size is returned in @var{uncompressed_size_p}.  If
    373  1.5  christos 	compression is unsupported, compression header size is returned
    374  1.5  christos 	with -1 and uncompressed size is returned with 0.
    375  1.1  christos */
    376  1.1  christos 
    377  1.1  christos bfd_boolean
    378  1.5  christos bfd_is_section_compressed_with_header (bfd *abfd, sec_ptr sec,
    379  1.5  christos 				       int *compression_header_size_p,
    380  1.5  christos 				       bfd_size_type *uncompressed_size_p)
    381  1.1  christos {
    382  1.5  christos   bfd_byte header[MAX_COMPRESSION_HEADER_SIZE];
    383  1.5  christos   int compression_header_size;
    384  1.5  christos   int header_size;
    385  1.1  christos   unsigned int saved = sec->compress_status;
    386  1.1  christos   bfd_boolean compressed;
    387  1.1  christos 
    388  1.5  christos   compression_header_size = bfd_get_compression_header_size (abfd, sec);
    389  1.5  christos   if (compression_header_size > MAX_COMPRESSION_HEADER_SIZE)
    390  1.5  christos     abort ();
    391  1.5  christos   header_size = compression_header_size ? compression_header_size : 12;
    392  1.5  christos 
    393  1.1  christos   /* Don't decompress the section.  */
    394  1.1  christos   sec->compress_status = COMPRESS_SECTION_NONE;
    395  1.1  christos 
    396  1.5  christos   /* Read the header.  */
    397  1.5  christos   if (bfd_get_section_contents (abfd, sec, header, 0, header_size))
    398  1.5  christos     {
    399  1.5  christos       if (compression_header_size == 0)
    400  1.5  christos         /* In this case, it should be "ZLIB" followed by the uncompressed
    401  1.5  christos 	   section size, 8 bytes in big-endian order.  */
    402  1.5  christos 	compressed = CONST_STRNEQ ((char*) header , "ZLIB");
    403  1.5  christos       else
    404  1.5  christos 	compressed = TRUE;
    405  1.5  christos     }
    406  1.5  christos   else
    407  1.3  christos     compressed = FALSE;
    408  1.3  christos 
    409  1.5  christos   *uncompressed_size_p = sec->size;
    410  1.5  christos   if (compressed)
    411  1.5  christos     {
    412  1.5  christos       if (compression_header_size != 0)
    413  1.5  christos 	{
    414  1.5  christos 	  if (!bfd_check_compression_header (abfd, header, sec,
    415  1.5  christos 					     uncompressed_size_p))
    416  1.5  christos 	    compression_header_size = -1;
    417  1.5  christos 	}
    418  1.5  christos       /* Check for the pathalogical case of a debug string section that
    419  1.5  christos 	 contains the string ZLIB.... as the first entry.  We assume that
    420  1.5  christos 	 no uncompressed .debug_str section would ever be big enough to
    421  1.5  christos 	 have the first byte of its (big-endian) size be non-zero.  */
    422  1.5  christos       else if (strcmp (sec->name, ".debug_str") == 0
    423  1.5  christos 	       && ISPRINT (header[4]))
    424  1.5  christos 	compressed = FALSE;
    425  1.5  christos       else
    426  1.5  christos 	*uncompressed_size_p = bfd_getb64 (header + 4);
    427  1.5  christos     }
    428  1.5  christos 
    429  1.1  christos   /* Restore compress_status.  */
    430  1.1  christos   sec->compress_status = saved;
    431  1.5  christos   *compression_header_size_p = compression_header_size;
    432  1.1  christos   return compressed;
    433  1.1  christos }
    434  1.1  christos 
    435  1.1  christos /*
    436  1.1  christos FUNCTION
    437  1.5  christos 	bfd_is_section_compressed
    438  1.5  christos 
    439  1.5  christos SYNOPSIS
    440  1.5  christos 	bfd_boolean bfd_is_section_compressed
    441  1.5  christos 	  (bfd *abfd, asection *section);
    442  1.5  christos 
    443  1.5  christos DESCRIPTION
    444  1.5  christos 	Return @code{TRUE} if @var{section} is compressed.
    445  1.5  christos */
    446  1.5  christos 
    447  1.5  christos bfd_boolean
    448  1.5  christos bfd_is_section_compressed (bfd *abfd, sec_ptr sec)
    449  1.5  christos {
    450  1.5  christos   int compression_header_size;
    451  1.5  christos   bfd_size_type uncompressed_size;
    452  1.5  christos   return (bfd_is_section_compressed_with_header (abfd, sec,
    453  1.5  christos 						 &compression_header_size,
    454  1.5  christos 						 &uncompressed_size)
    455  1.5  christos 	  && compression_header_size >= 0
    456  1.5  christos 	  && uncompressed_size > 0);
    457  1.5  christos }
    458  1.5  christos 
    459  1.5  christos /*
    460  1.5  christos FUNCTION
    461  1.1  christos 	bfd_init_section_decompress_status
    462  1.1  christos 
    463  1.1  christos SYNOPSIS
    464  1.1  christos 	bfd_boolean bfd_init_section_decompress_status
    465  1.1  christos 	  (bfd *abfd, asection *section);
    466  1.1  christos 
    467  1.1  christos DESCRIPTION
    468  1.1  christos 	Record compressed section size, update section size with
    469  1.1  christos 	decompressed size and set compress_status to
    470  1.1  christos 	DECOMPRESS_SECTION_SIZED.
    471  1.1  christos 
    472  1.1  christos 	Return @code{FALSE} if the section is not a valid compressed
    473  1.5  christos 	section.  Otherwise, return @code{TRUE}.
    474  1.1  christos */
    475  1.1  christos 
    476  1.1  christos bfd_boolean
    477  1.5  christos bfd_init_section_decompress_status (bfd *abfd, sec_ptr sec)
    478  1.1  christos {
    479  1.5  christos   bfd_byte header[MAX_COMPRESSION_HEADER_SIZE];
    480  1.5  christos   int compression_header_size;
    481  1.5  christos   int header_size;
    482  1.1  christos   bfd_size_type uncompressed_size;
    483  1.1  christos 
    484  1.5  christos   compression_header_size = bfd_get_compression_header_size (abfd, sec);
    485  1.5  christos   if (compression_header_size > MAX_COMPRESSION_HEADER_SIZE)
    486  1.5  christos     abort ();
    487  1.5  christos   header_size = compression_header_size ? compression_header_size : 12;
    488  1.5  christos 
    489  1.5  christos   /* Read the header.  */
    490  1.1  christos   if (sec->rawsize != 0
    491  1.1  christos       || sec->contents != NULL
    492  1.1  christos       || sec->compress_status != COMPRESS_SECTION_NONE
    493  1.5  christos       || !bfd_get_section_contents (abfd, sec, header, 0, header_size))
    494  1.1  christos     {
    495  1.1  christos       bfd_set_error (bfd_error_invalid_operation);
    496  1.1  christos       return FALSE;
    497  1.1  christos     }
    498  1.1  christos 
    499  1.5  christos   if (compression_header_size == 0)
    500  1.5  christos     {
    501  1.5  christos       /* In this case, it should be "ZLIB" followed by the uncompressed
    502  1.5  christos 	 section size, 8 bytes in big-endian order.  */
    503  1.5  christos       if (! CONST_STRNEQ ((char*) header, "ZLIB"))
    504  1.5  christos 	{
    505  1.5  christos 	  bfd_set_error (bfd_error_wrong_format);
    506  1.5  christos 	  return FALSE;
    507  1.5  christos 	}
    508  1.5  christos       uncompressed_size = bfd_getb64 (header + 4);
    509  1.5  christos     }
    510  1.5  christos   else if (!bfd_check_compression_header (abfd, header, sec,
    511  1.5  christos 					 &uncompressed_size))
    512  1.1  christos     {
    513  1.1  christos       bfd_set_error (bfd_error_wrong_format);
    514  1.1  christos       return FALSE;
    515  1.1  christos     }
    516  1.1  christos 
    517  1.1  christos   sec->compressed_size = sec->size;
    518  1.1  christos   sec->size = uncompressed_size;
    519  1.1  christos   sec->compress_status = DECOMPRESS_SECTION_SIZED;
    520  1.1  christos 
    521  1.1  christos   return TRUE;
    522  1.1  christos }
    523  1.1  christos 
    524  1.1  christos /*
    525  1.1  christos FUNCTION
    526  1.1  christos 	bfd_init_section_compress_status
    527  1.1  christos 
    528  1.1  christos SYNOPSIS
    529  1.1  christos 	bfd_boolean bfd_init_section_compress_status
    530  1.1  christos 	  (bfd *abfd, asection *section);
    531  1.1  christos 
    532  1.1  christos DESCRIPTION
    533  1.1  christos 	If open for read, compress section, update section size with
    534  1.1  christos 	compressed size and set compress_status to COMPRESS_SECTION_DONE.
    535  1.1  christos 
    536  1.1  christos 	Return @code{FALSE} if the section is not a valid compressed
    537  1.5  christos 	section.  Otherwise, return @code{TRUE}.
    538  1.1  christos */
    539  1.1  christos 
    540  1.1  christos bfd_boolean
    541  1.5  christos bfd_init_section_compress_status (bfd *abfd, sec_ptr sec)
    542  1.1  christos {
    543  1.1  christos   bfd_size_type uncompressed_size;
    544  1.1  christos   bfd_byte *uncompressed_buffer;
    545  1.1  christos   bfd_boolean ret;
    546  1.1  christos 
    547  1.1  christos   /* Error if not opened for read.  */
    548  1.1  christos   if (abfd->direction != read_direction
    549  1.1  christos       || sec->size == 0
    550  1.1  christos       || sec->rawsize != 0
    551  1.1  christos       || sec->contents != NULL
    552  1.1  christos       || sec->compress_status != COMPRESS_SECTION_NONE)
    553  1.1  christos     {
    554  1.1  christos       bfd_set_error (bfd_error_invalid_operation);
    555  1.1  christos       return FALSE;
    556  1.1  christos     }
    557  1.1  christos 
    558  1.1  christos   /* Read in the full section contents and compress it.  */
    559  1.1  christos   uncompressed_size = sec->size;
    560  1.1  christos   uncompressed_buffer = (bfd_byte *) bfd_malloc (uncompressed_size);
    561  1.1  christos   if (!bfd_get_section_contents (abfd, sec, uncompressed_buffer,
    562  1.1  christos 				 0, uncompressed_size))
    563  1.1  christos     ret = FALSE;
    564  1.1  christos   else
    565  1.5  christos     {
    566  1.5  christos       uncompressed_size = bfd_compress_section_contents (abfd, sec,
    567  1.5  christos 							 uncompressed_buffer,
    568  1.5  christos 							 uncompressed_size);
    569  1.5  christos       ret = uncompressed_size != 0;
    570  1.5  christos     }
    571  1.1  christos 
    572  1.1  christos   return ret;
    573  1.5  christos }
    574  1.5  christos 
    575  1.5  christos /*
    576  1.5  christos FUNCTION
    577  1.5  christos 	bfd_compress_section
    578  1.5  christos 
    579  1.5  christos SYNOPSIS
    580  1.5  christos 	bfd_boolean bfd_compress_section
    581  1.5  christos 	  (bfd *abfd, asection *section, bfd_byte *uncompressed_buffer);
    582  1.5  christos 
    583  1.5  christos DESCRIPTION
    584  1.5  christos 	If open for write, compress section, update section size with
    585  1.5  christos 	compressed size and set compress_status to COMPRESS_SECTION_DONE.
    586  1.5  christos 
    587  1.5  christos 	Return @code{FALSE} if compression fail.  Otherwise, return
    588  1.5  christos 	@code{TRUE}.
    589  1.5  christos */
    590  1.5  christos 
    591  1.5  christos bfd_boolean
    592  1.5  christos bfd_compress_section (bfd *abfd, sec_ptr sec, bfd_byte *uncompressed_buffer)
    593  1.5  christos {
    594  1.5  christos   bfd_size_type uncompressed_size = sec->size;
    595  1.5  christos 
    596  1.5  christos   /* Error if not opened for write.  */
    597  1.5  christos   if (abfd->direction != write_direction
    598  1.5  christos       || uncompressed_size == 0
    599  1.5  christos       || uncompressed_buffer == NULL
    600  1.5  christos       || sec->contents != NULL
    601  1.5  christos       || sec->compressed_size != 0
    602  1.5  christos       || sec->compress_status != COMPRESS_SECTION_NONE)
    603  1.5  christos     {
    604  1.5  christos       bfd_set_error (bfd_error_invalid_operation);
    605  1.5  christos       return FALSE;
    606  1.5  christos     }
    607  1.5  christos 
    608  1.5  christos   /* Compress it.  */
    609  1.5  christos   return bfd_compress_section_contents (abfd, sec, uncompressed_buffer,
    610  1.5  christos 					uncompressed_size) != 0;
    611  1.1  christos }
    612