/* Very simple "bfd" target, for GDB, the GNU debugger.

   Copyright (C) 2003, 2005, 2007-2012 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 "target.h"
#include "bfd-target.h"
#include "exec.h"
#include "gdb_bfd.h"

/* The object that is stored in the target_ops->to_data field has this
   type.  */
struct target_bfd_data
{
  /* The BFD we're wrapping.  */
  struct bfd *bfd;

  /* The section table build from the ALLOC sections in BFD.  Note
     that we can't rely on extracting the BFD from a random section in
     the table, since the table can be legitimately empty.  */
  struct target_section_table table;
};

static LONGEST
target_bfd_xfer_partial (struct target_ops *ops,
			 enum target_object object,
			 const char *annex, gdb_byte *readbuf,
			 const gdb_byte *writebuf,
			 ULONGEST offset, LONGEST len)
{
  switch (object)
    {
    case TARGET_OBJECT_MEMORY:
      {
	struct target_bfd_data *data = ops->to_data;
	return section_table_xfer_memory_partial (readbuf, writebuf,
						  offset, len,
						  data->table.sections,
						  data->table.sections_end,
						  NULL);
      }
    default:
      return -1;
    }
}

static struct target_section_table *
target_bfd_get_section_table (struct target_ops *ops)
{
  struct target_bfd_data *data = ops->to_data;
  return &data->table;
}

static void
target_bfd_xclose (struct target_ops *t, int quitting)
{
  struct target_bfd_data *data = t->to_data;

  gdb_bfd_unref (data->bfd);
  xfree (data->table.sections);
  xfree (data);
  xfree (t);
}

struct target_ops *
target_bfd_reopen (struct bfd *abfd)
{
  struct target_ops *t;
  struct target_bfd_data *data;

  data = XZALLOC (struct target_bfd_data);
  data->bfd = abfd;
  gdb_bfd_ref (abfd);
  build_section_table (abfd, &data->table.sections, &data->table.sections_end);

  t = XZALLOC (struct target_ops);
  t->to_shortname = "bfd";
  t->to_longname = _("BFD backed target");
  t->to_doc = _("You should never see this");
  t->to_get_section_table = target_bfd_get_section_table;
  t->to_xfer_partial = target_bfd_xfer_partial;
  t->to_xclose = target_bfd_xclose;
  t->to_data = data;

  return t;
}
