/* Read MiniDebugInfo data from an objfile.

   Copyright (C) 2012-2013 Free Software Foundation, Inc.

   This file is part of GDB.

   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, see <http://www.gnu.org/licenses/>.  */

#include "defs.h"
#include "gdb_bfd.h"
#include "gdb_string.h"
#include "symfile.h"
#include "objfiles.h"
#include "gdbcore.h"

#ifdef HAVE_LIBLZMA

#include <lzma.h>

/* Allocator function for LZMA.  */

static void *
alloc_lzma (void *opaque, size_t nmemb, size_t size)
{
  return xmalloc (nmemb * size);
}

/* Free function for LZMA.  */

static void
free_lzma (void *opaque, void *ptr)
{
  xfree (ptr);
}

/* The allocator object for LZMA.  Note that 'gdb_lzma_allocator'
   cannot be const due to the lzma library function prototypes.  */

static lzma_allocator gdb_lzma_allocator = { alloc_lzma, free_lzma, NULL };

/* Custom bfd_openr_iovec implementation to read compressed data from
   a section.  This keeps only the last decompressed block in memory
   to allow larger data without using to much memory.  */

struct lzma_stream
{
  /* Section of input BFD from which we are decoding data.  */
  asection *section;

  /* lzma library decompression state.  */
  lzma_index *index;

  /* Currently decoded block.  */
  bfd_size_type data_start;
  bfd_size_type data_end;
  gdb_byte *data;
};

/* bfd_openr_iovec OPEN_P implementation for
   find_separate_debug_file_in_section.  OPEN_CLOSURE is 'asection *'
   of the section to decompress.

   Return 'struct lzma_stream *' must be freed by caller by xfree, together
   with its INDEX lzma data.  */

static void *
lzma_open (struct bfd *nbfd, void *open_closure)
{
  asection *section = open_closure;
  bfd_size_type size, offset;
  lzma_stream_flags options;
  gdb_byte footer[LZMA_STREAM_HEADER_SIZE];
  gdb_byte *indexdata;
  lzma_index *index;
  int ret;
  uint64_t memlimit = UINT64_MAX;
  struct lzma_stream *lstream;
  size_t pos;

  size = bfd_get_section_size (section);
  offset = section->filepos + size - LZMA_STREAM_HEADER_SIZE;
  if (size < LZMA_STREAM_HEADER_SIZE
      || bfd_seek (section->owner, offset, SEEK_SET) != 0
      || bfd_bread (footer, LZMA_STREAM_HEADER_SIZE, section->owner)
         != LZMA_STREAM_HEADER_SIZE
      || lzma_stream_footer_decode (&options, footer) != LZMA_OK
      || offset < options.backward_size)
    {
      bfd_set_error (bfd_error_wrong_format);
      return NULL;
    }

  offset -= options.backward_size;
  indexdata = xmalloc (options.backward_size);
  index = NULL;
  pos = 0;
  if (bfd_seek (section->owner, offset, SEEK_SET) != 0
      || bfd_bread (indexdata, options.backward_size, section->owner)
         != options.backward_size
      || lzma_index_buffer_decode (&index, &memlimit, &gdb_lzma_allocator,
				   indexdata, &pos, options.backward_size)
         != LZMA_OK
      || lzma_index_size (index) != options.backward_size)
    {
      xfree (indexdata);
      bfd_set_error (bfd_error_wrong_format);
      return NULL;
    }
  xfree (indexdata);

  lstream = xzalloc (sizeof (struct lzma_stream));
  lstream->section = section;
  lstream->index = index;

  return lstream;
}

/* bfd_openr_iovec PREAD_P implementation for
   find_separate_debug_file_in_section.  Passed STREAM
   is 'struct lzma_stream *'.  */

static file_ptr
lzma_pread (struct bfd *nbfd, void *stream, void *buf, file_ptr nbytes,
	    file_ptr offset)
{
  struct lzma_stream *lstream = stream;
  bfd_size_type chunk_size;
  lzma_index_iter iter;
  gdb_byte *compressed, *uncompressed;
  file_ptr block_offset;
  lzma_filter filters[LZMA_FILTERS_MAX + 1];
  lzma_block block;
  size_t compressed_pos, uncompressed_pos;
  file_ptr res;

  res = 0;
  while (nbytes > 0)
    {
      if (lstream->data == NULL
	  || lstream->data_start > offset || offset >= lstream->data_end)
	{
	  asection *section = lstream->section;

	  lzma_index_iter_init (&iter, lstream->index);
	  if (lzma_index_iter_locate (&iter, offset))
	    break;

	  compressed = xmalloc (iter.block.total_size);
	  block_offset = section->filepos + iter.block.compressed_file_offset;
	  if (bfd_seek (section->owner, block_offset, SEEK_SET) != 0
	      || bfd_bread (compressed, iter.block.total_size, section->owner)
		 != iter.block.total_size)
	    {
	      xfree (compressed);
	      break;
	    }

	  uncompressed = xmalloc (iter.block.uncompressed_size);

	  memset (&block, 0, sizeof (block));
	  block.filters = filters;
	  block.header_size = lzma_block_header_size_decode (compressed[0]);
	  if (lzma_block_header_decode (&block, &gdb_lzma_allocator, compressed)
	      != LZMA_OK)
	    {
	      xfree (compressed);
	      xfree (uncompressed);
	      break;
	    }

	  compressed_pos = block.header_size;
	  uncompressed_pos = 0;
	  if (lzma_block_buffer_decode (&block, &gdb_lzma_allocator,
					compressed, &compressed_pos,
					iter.block.total_size,
					uncompressed, &uncompressed_pos,
					iter.block.uncompressed_size)
	      != LZMA_OK)
	    {
	      xfree (compressed);
	      xfree (uncompressed);
	      break;
	    }

	  xfree (compressed);

	  xfree (lstream->data);
	  lstream->data = uncompressed;
	  lstream->data_start = iter.block.uncompressed_file_offset;
	  lstream->data_end = (iter.block.uncompressed_file_offset
			       + iter.block.uncompressed_size);
	}

      chunk_size = min (nbytes, lstream->data_end - offset);
      memcpy (buf, lstream->data + offset - lstream->data_start, chunk_size);
      buf = (gdb_byte *) buf + chunk_size;
      offset += chunk_size;
      nbytes -= chunk_size;
      res += chunk_size;
    }

  return res;
}

/* bfd_openr_iovec CLOSE_P implementation for
   find_separate_debug_file_in_section.  Passed STREAM
   is 'struct lzma_stream *'.  */

static int
lzma_close (struct bfd *nbfd,
	    void *stream)
{
  struct lzma_stream *lstream = stream;

  lzma_index_end (lstream->index, &gdb_lzma_allocator);
  xfree (lstream->data);
  xfree (lstream);
  return 0;
}

/* bfd_openr_iovec STAT_P implementation for
   find_separate_debug_file_in_section.  Passed STREAM
   is 'struct lzma_stream *'.  */

static int
lzma_stat (struct bfd *abfd,
	   void *stream,
	   struct stat *sb)
{
  struct lzma_stream *lstream = stream;

  sb->st_size = lzma_index_uncompressed_size (lstream->index);
  return 0;
}

#endif /* HAVE_LIBLZMA  */

/* This looks for a xz compressed separate debug info object file embedded
   in a section called .gnu_debugdata.  See
   http://fedoraproject.org/wiki/Features/MiniDebugInfo
   or the "Separate Debug Sections" of the manual for details.
   If we find one we create a iovec based bfd that decompresses the
   object data on demand.  If we don't find one, return NULL.  */

bfd *
find_separate_debug_file_in_section (struct objfile *objfile)
{
  asection *section;
  bfd *abfd;

  if (objfile->obfd == NULL)
    return NULL;

  section = bfd_get_section_by_name (objfile->obfd, ".gnu_debugdata");
  if (section == NULL)
    return NULL;

#ifdef HAVE_LIBLZMA
  abfd = gdb_bfd_openr_iovec (objfile->name, gnutarget, lzma_open, section,
			      lzma_pread, lzma_close, lzma_stat);
  if (abfd == NULL)
    return NULL;

  if (!bfd_check_format (abfd, bfd_object))
    {
      warning (_("Cannot parse .gnu_debugdata section; not a BFD object"));
      gdb_bfd_unref (abfd);
      return NULL;
    }
#else
  warning (_("Cannot parse .gnu_debugdata section; LZMA support was "
	     "disabled at compile time"));
  abfd = NULL;
#endif /* !HAVE_LIBLZMA */

  return abfd;
}
