/* Compressed section support (intended for debug sections).
   Copyright 2008, 2010, 2011
   Free Software Foundation, Inc.

   This file is part of BFD, the Binary File Descriptor library.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
   MA 02110-1301, USA.  */

#include "config.h"
#include "sysdep.h"
#include "bfd.h"
#include "libbfd.h"
#ifdef HAVE_ZLIB_H
#include <zlib.h>
#endif

#ifdef HAVE_ZLIB_H
static bfd_boolean
decompress_contents (bfd_byte *compressed_buffer,
		     bfd_size_type compressed_size,
		     bfd_byte *uncompressed_buffer,
		     bfd_size_type uncompressed_size)
{
  z_stream strm;
  int rc;

  /* It is possible the section consists of several compressed
     buffers concatenated together, so we uncompress in a loop.  */
  strm.zalloc = NULL;
  strm.zfree = NULL;
  strm.opaque = NULL;
  strm.avail_in = compressed_size - 12;
  strm.next_in = (Bytef*) compressed_buffer + 12;
  strm.avail_out = uncompressed_size;

  rc = inflateInit (&strm);
  while (strm.avail_in > 0)
    {
      if (rc != Z_OK)
	return FALSE;
      strm.next_out = ((Bytef*) uncompressed_buffer
                       + (uncompressed_size - strm.avail_out));
      rc = inflate (&strm, Z_FINISH);
      if (rc != Z_STREAM_END)
	return FALSE;
      rc = inflateReset (&strm);
    }
  rc = inflateEnd (&strm);
  return rc == Z_OK && strm.avail_out == 0;
}
#endif

/*
FUNCTION
	bfd_compress_section_contents

SYNOPSIS
	bfd_boolean bfd_compress_section_contents
	  (bfd *abfd, asection *section, bfd_byte *uncompressed_buffer,
	   bfd_size_type uncompressed_size);

DESCRIPTION

	Compress data of the size specified in @var{uncompressed_size}
	and pointed to by @var{uncompressed_buffer} using zlib and store
	as the contents field.  This function assumes the contents
	field was allocated using bfd_malloc() or equivalent.  If zlib
	is not installed on this machine, the input is unmodified.

	Return @code{TRUE} if the full section contents is compressed 
	successfully.
*/

bfd_boolean
bfd_compress_section_contents (bfd *abfd ATTRIBUTE_UNUSED,
			       sec_ptr sec ATTRIBUTE_UNUSED,
			       bfd_byte *uncompressed_buffer ATTRIBUTE_UNUSED,
			       bfd_size_type uncompressed_size ATTRIBUTE_UNUSED)
{
#ifndef HAVE_ZLIB_H
  bfd_set_error (bfd_error_invalid_operation);
  return FALSE;
#else
  uLong compressed_size;
  bfd_byte *compressed_buffer;

  compressed_size = compressBound (uncompressed_size) + 12;
  compressed_buffer = (bfd_byte *) bfd_malloc (compressed_size);

  if (compressed_buffer == NULL)
    return FALSE;

  if (compress ((Bytef*) compressed_buffer + 12,
		&compressed_size,
		(const Bytef*) uncompressed_buffer,
		uncompressed_size) != Z_OK)
    {
      free (compressed_buffer);
      bfd_set_error (bfd_error_bad_value);
      return FALSE;
    }

  /* Write the zlib header.  In this case, it should be "ZLIB" followed
     by the uncompressed section size, 8 bytes in big-endian order.  */
  memcpy (compressed_buffer, "ZLIB", 4);
  compressed_buffer[11] = uncompressed_size; uncompressed_size >>= 8;
  compressed_buffer[10] = uncompressed_size; uncompressed_size >>= 8;
  compressed_buffer[9] = uncompressed_size; uncompressed_size >>= 8;
  compressed_buffer[8] = uncompressed_size; uncompressed_size >>= 8;
  compressed_buffer[7] = uncompressed_size; uncompressed_size >>= 8;
  compressed_buffer[6] = uncompressed_size; uncompressed_size >>= 8;
  compressed_buffer[5] = uncompressed_size; uncompressed_size >>= 8;
  compressed_buffer[4] = uncompressed_size;
  compressed_size += 12;

  /* Free the uncompressed contents if we compress in place.  */
  if (uncompressed_buffer == sec->contents)
    free (uncompressed_buffer);

  sec->contents = compressed_buffer;
  sec->size = compressed_size;
  sec->compress_status = COMPRESS_SECTION_DONE;

  return TRUE;
#endif  /* HAVE_ZLIB_H */
}

/*
FUNCTION
	bfd_get_full_section_contents

SYNOPSIS
	bfd_boolean bfd_get_full_section_contents
	  (bfd *abfd, asection *section, bfd_byte **ptr);

DESCRIPTION
	Read all data from @var{section} in BFD @var{abfd}, decompress
	if needed, and store in @var{*ptr}.  If @var{*ptr} is NULL,
	return @var{*ptr} with memory malloc'd by this function.  

	Return @code{TRUE} if the full section contents is retrieved
	successfully.
*/

bfd_boolean
bfd_get_full_section_contents (bfd *abfd, sec_ptr sec, bfd_byte **ptr)
{
  bfd_size_type sz;
  bfd_byte *p = *ptr;
#ifdef HAVE_ZLIB_H
  bfd_boolean ret;
  bfd_size_type compressed_size;
  bfd_size_type uncompressed_size;
  bfd_size_type rawsize;
  bfd_byte *compressed_buffer;
  bfd_byte *uncompressed_buffer;
#endif

  if (abfd->direction != write_direction && sec->rawsize != 0)
    sz = sec->rawsize;
  else
    sz = sec->size;
  if (sz == 0)
    return TRUE;

  switch (sec->compress_status)
    {
    case COMPRESS_SECTION_NONE:
      if (p == NULL)
	{
	  p = (bfd_byte *) bfd_malloc (sz);
	  if (p == NULL)
	    return FALSE;
	}
      if (!bfd_get_section_contents (abfd, sec, p, 0, sz))
	{
	  if (*ptr != p)
	    free (p);
	  return FALSE;
	}
      *ptr = p;
      return TRUE;

    case DECOMPRESS_SECTION_SIZED:
#ifndef HAVE_ZLIB_H
      bfd_set_error (bfd_error_invalid_operation);
      return FALSE;
#else
      /* Read in the full compressed section contents.  */
      uncompressed_size = sec->size;
      compressed_size = sec->compressed_size;
      compressed_buffer = (bfd_byte *) bfd_malloc (compressed_size);
      if (compressed_buffer == NULL)
	return FALSE;
      rawsize = sec->rawsize;
      /* Clear rawsize, set size to compressed size and set compress_status
	 to COMPRESS_SECTION_NONE.  If the compressed size is bigger than
	 the uncompressed size, bfd_get_section_contents will fail.  */
      sec->rawsize = 0;
      sec->size = compressed_size;
      sec->compress_status = COMPRESS_SECTION_NONE;
      ret = bfd_get_section_contents (abfd, sec, compressed_buffer,
				      0, compressed_size);
      /* Restore rawsize and size.  */
      sec->rawsize = rawsize;
      sec->size = uncompressed_size;
      sec->compress_status = DECOMPRESS_SECTION_SIZED;
      if (!ret)
	goto fail_compressed;

      uncompressed_buffer = (bfd_byte *) bfd_malloc (uncompressed_size);
      if (uncompressed_buffer == NULL)
	goto fail_compressed;

      if (!decompress_contents (compressed_buffer, compressed_size,
				uncompressed_buffer, uncompressed_size))
	{
	  bfd_set_error (bfd_error_bad_value);
	  free (uncompressed_buffer);
	fail_compressed:
	  free (compressed_buffer);
	  return FALSE;
	}

      free (compressed_buffer);
      sec->contents = uncompressed_buffer;
      sec->compress_status = COMPRESS_SECTION_DONE;
      /* Fall thru */
#endif

    case COMPRESS_SECTION_DONE:
      if (p == NULL)
	{
	  p = (bfd_byte *) bfd_malloc (sz);
	  if (p == NULL)
	    return FALSE;
	  *ptr = p;
	}
      memcpy (p, sec->contents, sz);
      return TRUE;

    default:
      abort ();
    }
}

/*
FUNCTION
	bfd_is_section_compressed

SYNOPSIS
	bfd_boolean bfd_is_section_compressed
	  (bfd *abfd, asection *section);

DESCRIPTION
	Return @code{TRUE} if @var{section} is compressed.
*/

bfd_boolean
bfd_is_section_compressed (bfd *abfd, sec_ptr sec)
{
  bfd_byte compressed_buffer [12];

  /* Read the zlib header.  In this case, it should be "ZLIB" followed
     by the uncompressed section size, 8 bytes in big-endian order.  */
  return (bfd_get_section_contents (abfd, sec, compressed_buffer, 0, 12)
	  && CONST_STRNEQ ((char*) compressed_buffer, "ZLIB"));
}

/*
FUNCTION
	bfd_init_section_decompress_status

SYNOPSIS
	bfd_boolean bfd_init_section_decompress_status
	  (bfd *abfd, asection *section);

DESCRIPTION
	Record compressed section size, update section size with
	decompressed size and set compress_status to
	DECOMPRESS_SECTION_SIZED.

	Return @code{FALSE} if the section is not a valid compressed
	section or zlib is not installed on this machine.  Otherwise,
	return @code{TRUE}.
*/

bfd_boolean
bfd_init_section_decompress_status (bfd *abfd ATTRIBUTE_UNUSED,
				    sec_ptr sec ATTRIBUTE_UNUSED)
{
#ifndef HAVE_ZLIB_H
  bfd_set_error (bfd_error_invalid_operation);
  return FALSE;
#else
  bfd_byte compressed_buffer [12];
  bfd_size_type uncompressed_size;

  if (sec->rawsize != 0
      || sec->contents != NULL
      || sec->compress_status != COMPRESS_SECTION_NONE
      || !bfd_get_section_contents (abfd, sec, compressed_buffer, 0, 12))
    {
      bfd_set_error (bfd_error_invalid_operation);
      return FALSE;
    }

  /* Read the zlib header.  In this case, it should be "ZLIB" followed
     by the uncompressed section size, 8 bytes in big-endian order.  */
  if (! CONST_STRNEQ ((char*) compressed_buffer, "ZLIB"))
    {
      bfd_set_error (bfd_error_wrong_format);
      return FALSE;
    }

  uncompressed_size = compressed_buffer[4]; uncompressed_size <<= 8;
  uncompressed_size += compressed_buffer[5]; uncompressed_size <<= 8;
  uncompressed_size += compressed_buffer[6]; uncompressed_size <<= 8;
  uncompressed_size += compressed_buffer[7]; uncompressed_size <<= 8;
  uncompressed_size += compressed_buffer[8]; uncompressed_size <<= 8;
  uncompressed_size += compressed_buffer[9]; uncompressed_size <<= 8;
  uncompressed_size += compressed_buffer[10]; uncompressed_size <<= 8;
  uncompressed_size += compressed_buffer[11];

  sec->compressed_size = sec->size;
  sec->size = uncompressed_size;
  sec->compress_status = DECOMPRESS_SECTION_SIZED;

  return TRUE;
#endif
}

/*
FUNCTION
	bfd_init_section_compress_status

SYNOPSIS
	bfd_boolean bfd_init_section_compress_status
	  (bfd *abfd, asection *section);

DESCRIPTION
	If open for read, compress section, update section size with
	compressed size and set compress_status to COMPRESS_SECTION_DONE.

	Return @code{FALSE} if the section is not a valid compressed
	section or zlib is not installed on this machine.  Otherwise,
	return @code{TRUE}.
*/

bfd_boolean
bfd_init_section_compress_status (bfd *abfd ATTRIBUTE_UNUSED,
				  sec_ptr sec ATTRIBUTE_UNUSED)
{
#ifndef HAVE_ZLIB_H
  bfd_set_error (bfd_error_invalid_operation);
  return FALSE;
#else
  bfd_size_type uncompressed_size;
  bfd_byte *uncompressed_buffer;
  bfd_boolean ret;

  /* Error if not opened for read.  */
  if (abfd->direction != read_direction
      || sec->size == 0
      || sec->rawsize != 0
      || sec->contents != NULL
      || sec->compress_status != COMPRESS_SECTION_NONE)
    {
      bfd_set_error (bfd_error_invalid_operation);
      return FALSE;
    }

  /* Read in the full section contents and compress it.  */
  uncompressed_size = sec->size;
  uncompressed_buffer = (bfd_byte *) bfd_malloc (uncompressed_size);
  if (!bfd_get_section_contents (abfd, sec, uncompressed_buffer,
				 0, uncompressed_size))
    ret = FALSE;
  else
    ret = bfd_compress_section_contents (abfd, sec,
					 uncompressed_buffer,
					 uncompressed_size);

  free (uncompressed_buffer);
  return ret;
#endif
}
