Subversion Repositories Kolibri OS

Rev

Rev 5197 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

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