/* Compressed section support (intended for debug sections).
   Copyright 2008, 2010, 2011, 2012
   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 "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 && strm.avail_out > 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 save_size;
  bfd_size_type save_rawsize;
  bfd_byte *compressed_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.  */
      compressed_buffer = (bfd_byte *) bfd_malloc (sec->compressed_size);
      if (compressed_buffer == NULL)
	return FALSE;
      save_rawsize = sec->rawsize;
      save_size = sec->size;
      /* 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 = sec->compressed_size;
      sec->compress_status = COMPRESS_SECTION_NONE;
      ret = bfd_get_section_contents (abfd, sec, compressed_buffer,
				      0, sec->compressed_size);
      /* Restore rawsize and size.  */
      sec->rawsize = save_rawsize;
      sec->size = save_size;
      sec->compress_status = DECOMPRESS_SECTION_SIZED;
      if (!ret)
	goto fail_compressed;

      if (p == NULL)
	p = (bfd_byte *) bfd_malloc (sz);
      if (p == NULL)
	goto fail_compressed;

      if (!decompress_contents (compressed_buffer, sec->compressed_size, p, sz))
	{
	  bfd_set_error (bfd_error_bad_value);
	  if (p != *ptr)
	    free (p);
	fail_compressed:
	  free (compressed_buffer);
	  return FALSE;
	}

      free (compressed_buffer);
      *ptr = p;
      return TRUE;
#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_cache_section_contents

SYNOPSIS
	void bfd_cache_section_contents
	  (asection *sec, void *contents);

DESCRIPTION
	Stash @var(contents) so any following reads of @var(sec) do
	not need to decompress again.
*/

void
bfd_cache_section_contents (asection *sec, void *contents)
{
  if (sec->compress_status == DECOMPRESS_SECTION_SIZED)
    sec->compress_status = COMPRESS_SECTION_DONE;
  sec->contents = contents;
  sec->flags |= SEC_IN_MEMORY;
}


/*
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];
  unsigned int saved = sec->compress_status;
  bfd_boolean compressed;

  /* Don't decompress the section.  */
  sec->compress_status = COMPRESS_SECTION_NONE;

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

  /* Restore compress_status.  */
  sec->compress_status = saved;
  return compressed;
}

/*
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
}
