Home | History | Annotate | Line # | Download | only in bfd
compress.c revision 1.1.1.4
      1 /* Compressed section support (intended for debug sections).
      2    Copyright (C) 2008-2015 Free Software Foundation, Inc.
      3 
      4    This file is part of BFD, the Binary File Descriptor library.
      5 
      6    This program is free software; you can redistribute it and/or modify
      7    it under the terms of the GNU General Public License as published by
      8    the Free Software Foundation; either version 3 of the License, or
      9    (at your option) any later version.
     10 
     11    This program is distributed in the hope that it will be useful,
     12    but WITHOUT ANY WARRANTY; without even the implied warranty of
     13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14    GNU General Public License for more details.
     15 
     16    You should have received a copy of the GNU General Public License
     17    along with this program; if not, write to the Free Software
     18    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
     19    MA 02110-1301, USA.  */
     20 
     21 #include "sysdep.h"
     22 #include "bfd.h"
     23 #include "libbfd.h"
     24 #ifdef HAVE_ZLIB_H
     25 #include <zlib.h>
     26 #endif
     27 #include "safe-ctype.h"
     28 
     29 #ifdef HAVE_ZLIB_H
     30 static bfd_boolean
     31 decompress_contents (bfd_byte *compressed_buffer,
     32 		     bfd_size_type compressed_size,
     33 		     bfd_byte *uncompressed_buffer,
     34 		     bfd_size_type uncompressed_size)
     35 {
     36   z_stream strm;
     37   int rc;
     38 
     39   /* It is possible the section consists of several compressed
     40      buffers concatenated together, so we uncompress in a loop.  */
     41   strm.zalloc = NULL;
     42   strm.zfree = NULL;
     43   strm.opaque = NULL;
     44   strm.avail_in = compressed_size - 12;
     45   strm.next_in = (Bytef*) compressed_buffer + 12;
     46   strm.avail_out = uncompressed_size;
     47 
     48   BFD_ASSERT (Z_OK == 0);
     49   rc = inflateInit (&strm);
     50   while (strm.avail_in > 0 && strm.avail_out > 0)
     51     {
     52       if (rc != Z_OK)
     53 	break;
     54       strm.next_out = ((Bytef*) uncompressed_buffer
     55                        + (uncompressed_size - strm.avail_out));
     56       rc = inflate (&strm, Z_FINISH);
     57       if (rc != Z_STREAM_END)
     58 	break;
     59       rc = inflateReset (&strm);
     60     }
     61   rc |= inflateEnd (&strm);
     62   return rc == Z_OK && strm.avail_out == 0;
     63 }
     64 #endif
     65 
     66 /*
     67 FUNCTION
     68 	bfd_compress_section_contents
     69 
     70 SYNOPSIS
     71 	bfd_boolean bfd_compress_section_contents
     72 	  (bfd *abfd, asection *section, bfd_byte *uncompressed_buffer,
     73 	   bfd_size_type uncompressed_size);
     74 
     75 DESCRIPTION
     76 
     77 	Compress data of the size specified in @var{uncompressed_size}
     78 	and pointed to by @var{uncompressed_buffer} using zlib and store
     79 	as the contents field.  This function assumes the contents
     80 	field was allocated using bfd_malloc() or equivalent.  If zlib
     81 	is not installed on this machine, the input is unmodified.
     82 
     83 	Return @code{TRUE} if the full section contents is compressed
     84 	successfully.
     85 */
     86 
     87 bfd_boolean
     88 bfd_compress_section_contents (bfd *abfd ATTRIBUTE_UNUSED,
     89 			       sec_ptr sec ATTRIBUTE_UNUSED,
     90 			       bfd_byte *uncompressed_buffer ATTRIBUTE_UNUSED,
     91 			       bfd_size_type uncompressed_size ATTRIBUTE_UNUSED)
     92 {
     93 #ifndef HAVE_ZLIB_H
     94   bfd_set_error (bfd_error_invalid_operation);
     95   return FALSE;
     96 #else
     97   uLong compressed_size;
     98   bfd_byte *compressed_buffer;
     99 
    100   compressed_size = compressBound (uncompressed_size) + 12;
    101   compressed_buffer = (bfd_byte *) bfd_malloc (compressed_size);
    102 
    103   if (compressed_buffer == NULL)
    104     return FALSE;
    105 
    106   if (compress ((Bytef*) compressed_buffer + 12,
    107 		&compressed_size,
    108 		(const Bytef*) uncompressed_buffer,
    109 		uncompressed_size) != Z_OK)
    110     {
    111       free (compressed_buffer);
    112       bfd_set_error (bfd_error_bad_value);
    113       return FALSE;
    114     }
    115 
    116   /* Write the zlib header.  In this case, it should be "ZLIB" followed
    117      by the uncompressed section size, 8 bytes in big-endian order.  */
    118   memcpy (compressed_buffer, "ZLIB", 4);
    119   compressed_buffer[11] = uncompressed_size; uncompressed_size >>= 8;
    120   compressed_buffer[10] = uncompressed_size; uncompressed_size >>= 8;
    121   compressed_buffer[9] = uncompressed_size; uncompressed_size >>= 8;
    122   compressed_buffer[8] = uncompressed_size; uncompressed_size >>= 8;
    123   compressed_buffer[7] = uncompressed_size; uncompressed_size >>= 8;
    124   compressed_buffer[6] = uncompressed_size; uncompressed_size >>= 8;
    125   compressed_buffer[5] = uncompressed_size; uncompressed_size >>= 8;
    126   compressed_buffer[4] = uncompressed_size;
    127   compressed_size += 12;
    128 
    129   /* Free the uncompressed contents if we compress in place.  */
    130   if (uncompressed_buffer == sec->contents)
    131     free (uncompressed_buffer);
    132 
    133   sec->contents = compressed_buffer;
    134   sec->size = compressed_size;
    135   sec->compress_status = COMPRESS_SECTION_DONE;
    136 
    137   return TRUE;
    138 #endif  /* HAVE_ZLIB_H */
    139 }
    140 
    141 /*
    142 FUNCTION
    143 	bfd_get_full_section_contents
    144 
    145 SYNOPSIS
    146 	bfd_boolean bfd_get_full_section_contents
    147 	  (bfd *abfd, asection *section, bfd_byte **ptr);
    148 
    149 DESCRIPTION
    150 	Read all data from @var{section} in BFD @var{abfd}, decompress
    151 	if needed, and store in @var{*ptr}.  If @var{*ptr} is NULL,
    152 	return @var{*ptr} with memory malloc'd by this function.
    153 
    154 	Return @code{TRUE} if the full section contents is retrieved
    155 	successfully.  If the section has no contents then this function
    156 	returns @code{TRUE} but @var{*ptr} is set to NULL.
    157 */
    158 
    159 bfd_boolean
    160 bfd_get_full_section_contents (bfd *abfd, sec_ptr sec, bfd_byte **ptr)
    161 {
    162   bfd_size_type sz;
    163   bfd_byte *p = *ptr;
    164 #ifdef HAVE_ZLIB_H
    165   bfd_boolean ret;
    166   bfd_size_type save_size;
    167   bfd_size_type save_rawsize;
    168   bfd_byte *compressed_buffer;
    169 #endif
    170 
    171   if (abfd->direction != write_direction && sec->rawsize != 0)
    172     sz = sec->rawsize;
    173   else
    174     sz = sec->size;
    175   if (sz == 0)
    176     {
    177       *ptr = NULL;
    178       return TRUE;
    179     }
    180 
    181   switch (sec->compress_status)
    182     {
    183     case COMPRESS_SECTION_NONE:
    184       if (p == NULL)
    185 	{
    186 	  p = (bfd_byte *) bfd_malloc (sz);
    187 	  if (p == NULL)
    188 	    return FALSE;
    189 	}
    190 
    191       if (!bfd_get_section_contents (abfd, sec, p, 0, sz))
    192 	{
    193 	  if (*ptr != p)
    194 	    free (p);
    195 	  return FALSE;
    196 	}
    197       *ptr = p;
    198       return TRUE;
    199 
    200     case DECOMPRESS_SECTION_SIZED:
    201 #ifndef HAVE_ZLIB_H
    202       bfd_set_error (bfd_error_invalid_operation);
    203       return FALSE;
    204 #else
    205       /* Read in the full compressed section contents.  */
    206       compressed_buffer = (bfd_byte *) bfd_malloc (sec->compressed_size);
    207       if (compressed_buffer == NULL)
    208 	return FALSE;
    209       save_rawsize = sec->rawsize;
    210       save_size = sec->size;
    211       /* Clear rawsize, set size to compressed size and set compress_status
    212 	 to COMPRESS_SECTION_NONE.  If the compressed size is bigger than
    213 	 the uncompressed size, bfd_get_section_contents will fail.  */
    214       sec->rawsize = 0;
    215       sec->size = sec->compressed_size;
    216       sec->compress_status = COMPRESS_SECTION_NONE;
    217       ret = bfd_get_section_contents (abfd, sec, compressed_buffer,
    218 				      0, sec->compressed_size);
    219       /* Restore rawsize and size.  */
    220       sec->rawsize = save_rawsize;
    221       sec->size = save_size;
    222       sec->compress_status = DECOMPRESS_SECTION_SIZED;
    223       if (!ret)
    224 	goto fail_compressed;
    225 
    226       if (p == NULL)
    227 	p = (bfd_byte *) bfd_malloc (sz);
    228       if (p == NULL)
    229 	goto fail_compressed;
    230 
    231       if (!decompress_contents (compressed_buffer, sec->compressed_size, p, sz))
    232 	{
    233 	  bfd_set_error (bfd_error_bad_value);
    234 	  if (p != *ptr)
    235 	    free (p);
    236 	fail_compressed:
    237 	  free (compressed_buffer);
    238 	  return FALSE;
    239 	}
    240 
    241       free (compressed_buffer);
    242       *ptr = p;
    243       return TRUE;
    244 #endif
    245 
    246     case COMPRESS_SECTION_DONE:
    247       if (sec->contents == NULL)
    248 	return FALSE;
    249       if (p == NULL)
    250 	{
    251 	  p = (bfd_byte *) bfd_malloc (sz);
    252 	  if (p == NULL)
    253 	    return FALSE;
    254 	  *ptr = p;
    255 	}
    256       /* PR 17512; file: 5bc29788.  */
    257       if (p != sec->contents)
    258 	memcpy (p, sec->contents, sz);
    259       return TRUE;
    260 
    261     default:
    262       abort ();
    263     }
    264 }
    265 
    266 /*
    267 FUNCTION
    268 	bfd_cache_section_contents
    269 
    270 SYNOPSIS
    271 	void bfd_cache_section_contents
    272 	  (asection *sec, void *contents);
    273 
    274 DESCRIPTION
    275 	Stash @var(contents) so any following reads of @var(sec) do
    276 	not need to decompress again.
    277 */
    278 
    279 void
    280 bfd_cache_section_contents (asection *sec, void *contents)
    281 {
    282   if (sec->compress_status == DECOMPRESS_SECTION_SIZED)
    283     sec->compress_status = COMPRESS_SECTION_DONE;
    284   sec->contents = contents;
    285   sec->flags |= SEC_IN_MEMORY;
    286 }
    287 
    288 
    289 /*
    290 FUNCTION
    291 	bfd_is_section_compressed
    292 
    293 SYNOPSIS
    294 	bfd_boolean bfd_is_section_compressed
    295 	  (bfd *abfd, asection *section);
    296 
    297 DESCRIPTION
    298 	Return @code{TRUE} if @var{section} is compressed.
    299 */
    300 
    301 bfd_boolean
    302 bfd_is_section_compressed (bfd *abfd, sec_ptr sec)
    303 {
    304   bfd_byte compressed_buffer [12];
    305   unsigned int saved = sec->compress_status;
    306   bfd_boolean compressed;
    307 
    308   /* Don't decompress the section.  */
    309   sec->compress_status = COMPRESS_SECTION_NONE;
    310 
    311   /* Read the zlib header.  In this case, it should be "ZLIB" followed
    312      by the uncompressed section size, 8 bytes in big-endian order.  */
    313   compressed = (bfd_get_section_contents (abfd, sec, compressed_buffer, 0, 12)
    314 		&& CONST_STRNEQ ((char*) compressed_buffer, "ZLIB"));
    315 
    316   /* Check for the pathalogical case of a debug string section that
    317      contains the string ZLIB.... as the first entry.  We assume that
    318      no uncompressed .debug_str section would ever be big enough to
    319      have the first byte of its (big-endian) size be non-zero.  */
    320   if (compressed
    321       && strcmp (sec->name, ".debug_str") == 0
    322       && ISPRINT (compressed_buffer[4]))
    323     compressed = FALSE;
    324 
    325   /* Restore compress_status.  */
    326   sec->compress_status = saved;
    327   return compressed;
    328 }
    329 
    330 /*
    331 FUNCTION
    332 	bfd_init_section_decompress_status
    333 
    334 SYNOPSIS
    335 	bfd_boolean bfd_init_section_decompress_status
    336 	  (bfd *abfd, asection *section);
    337 
    338 DESCRIPTION
    339 	Record compressed section size, update section size with
    340 	decompressed size and set compress_status to
    341 	DECOMPRESS_SECTION_SIZED.
    342 
    343 	Return @code{FALSE} if the section is not a valid compressed
    344 	section or zlib is not installed on this machine.  Otherwise,
    345 	return @code{TRUE}.
    346 */
    347 
    348 bfd_boolean
    349 bfd_init_section_decompress_status (bfd *abfd ATTRIBUTE_UNUSED,
    350 				    sec_ptr sec ATTRIBUTE_UNUSED)
    351 {
    352 #ifndef HAVE_ZLIB_H
    353   bfd_set_error (bfd_error_invalid_operation);
    354   return FALSE;
    355 #else
    356   bfd_byte compressed_buffer [12];
    357   bfd_size_type uncompressed_size;
    358 
    359   if (sec->rawsize != 0
    360       || sec->contents != NULL
    361       || sec->compress_status != COMPRESS_SECTION_NONE
    362       || !bfd_get_section_contents (abfd, sec, compressed_buffer, 0, 12))
    363     {
    364       bfd_set_error (bfd_error_invalid_operation);
    365       return FALSE;
    366     }
    367 
    368   /* Read the zlib header.  In this case, it should be "ZLIB" followed
    369      by the uncompressed section size, 8 bytes in big-endian order.  */
    370   if (! CONST_STRNEQ ((char*) compressed_buffer, "ZLIB"))
    371     {
    372       bfd_set_error (bfd_error_wrong_format);
    373       return FALSE;
    374     }
    375 
    376   uncompressed_size = compressed_buffer[4]; uncompressed_size <<= 8;
    377   uncompressed_size += compressed_buffer[5]; uncompressed_size <<= 8;
    378   uncompressed_size += compressed_buffer[6]; uncompressed_size <<= 8;
    379   uncompressed_size += compressed_buffer[7]; uncompressed_size <<= 8;
    380   uncompressed_size += compressed_buffer[8]; uncompressed_size <<= 8;
    381   uncompressed_size += compressed_buffer[9]; uncompressed_size <<= 8;
    382   uncompressed_size += compressed_buffer[10]; uncompressed_size <<= 8;
    383   uncompressed_size += compressed_buffer[11];
    384 
    385   sec->compressed_size = sec->size;
    386   sec->size = uncompressed_size;
    387   sec->compress_status = DECOMPRESS_SECTION_SIZED;
    388 
    389   return TRUE;
    390 #endif
    391 }
    392 
    393 /*
    394 FUNCTION
    395 	bfd_init_section_compress_status
    396 
    397 SYNOPSIS
    398 	bfd_boolean bfd_init_section_compress_status
    399 	  (bfd *abfd, asection *section);
    400 
    401 DESCRIPTION
    402 	If open for read, compress section, update section size with
    403 	compressed size and set compress_status to COMPRESS_SECTION_DONE.
    404 
    405 	Return @code{FALSE} if the section is not a valid compressed
    406 	section or zlib is not installed on this machine.  Otherwise,
    407 	return @code{TRUE}.
    408 */
    409 
    410 bfd_boolean
    411 bfd_init_section_compress_status (bfd *abfd ATTRIBUTE_UNUSED,
    412 				  sec_ptr sec ATTRIBUTE_UNUSED)
    413 {
    414 #ifndef HAVE_ZLIB_H
    415   bfd_set_error (bfd_error_invalid_operation);
    416   return FALSE;
    417 #else
    418   bfd_size_type uncompressed_size;
    419   bfd_byte *uncompressed_buffer;
    420   bfd_boolean ret;
    421 
    422   /* Error if not opened for read.  */
    423   if (abfd->direction != read_direction
    424       || sec->size == 0
    425       || sec->rawsize != 0
    426       || sec->contents != NULL
    427       || sec->compress_status != COMPRESS_SECTION_NONE)
    428     {
    429       bfd_set_error (bfd_error_invalid_operation);
    430       return FALSE;
    431     }
    432 
    433   /* Read in the full section contents and compress it.  */
    434   uncompressed_size = sec->size;
    435   uncompressed_buffer = (bfd_byte *) bfd_malloc (uncompressed_size);
    436   if (!bfd_get_section_contents (abfd, sec, uncompressed_buffer,
    437 				 0, uncompressed_size))
    438     ret = FALSE;
    439   else
    440     ret = bfd_compress_section_contents (abfd, sec,
    441 					 uncompressed_buffer,
    442 					 uncompressed_size);
    443 
    444   free (uncompressed_buffer);
    445   return ret;
    446 #endif
    447 }
    448