/* Definitions for targets which report shared library events.

   Copyright (C) 2007, 2008, 2009 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 "objfiles.h"
#include "solist.h"
#include "symtab.h"
#include "symfile.h"
#include "target.h"
#include "vec.h"
#include "solib-target.h"

#include "gdb_string.h"

DEF_VEC_O(CORE_ADDR);

/* Private data for each loaded library.  */
struct lm_info
{
  /* The library's name.  The name is normally kept in the struct
     so_list; it is only here during XML parsing.  */
  char *name;

  /* The target can either specify segment bases or section bases, not
     both.  */

  /* The base addresses for each independently relocatable segment of
     this shared library.  */
  VEC(CORE_ADDR) *segment_bases;

  /* The base addresses for each independently allocatable,
     relocatable section of this shared library.  */
  VEC(CORE_ADDR) *section_bases;

  /* The cached offsets for each section of this shared library,
     determined from SEGMENT_BASES, or SECTION_BASES.  */
  struct section_offsets *offsets;
};

typedef struct lm_info *lm_info_p;
DEF_VEC_P(lm_info_p);

#if !defined(HAVE_LIBEXPAT)

static VEC(lm_info_p) *
solib_target_parse_libraries (const char *library)
{
  static int have_warned;

  if (!have_warned)
    {
      have_warned = 1;
      warning (_("Can not parse XML library list; XML support was disabled "
		 "at compile time"));
    }

  return NULL;
}

#else /* HAVE_LIBEXPAT */

#include "xml-support.h"

/* Handle the start of a <segment> element.  */

static void
library_list_start_segment (struct gdb_xml_parser *parser,
			    const struct gdb_xml_element *element,
			    void *user_data, VEC(gdb_xml_value_s) *attributes)
{
  VEC(lm_info_p) **list = user_data;
  struct lm_info *last = VEC_last (lm_info_p, *list);
  ULONGEST *address_p = VEC_index (gdb_xml_value_s, attributes, 0)->value;
  CORE_ADDR address = (CORE_ADDR) *address_p;

  if (last->section_bases != NULL)
    gdb_xml_error (parser,
		   _("Library list with both segments and sections"));

  VEC_safe_push (CORE_ADDR, last->segment_bases, &address);
}

static void
library_list_start_section (struct gdb_xml_parser *parser,
			    const struct gdb_xml_element *element,
			    void *user_data, VEC(gdb_xml_value_s) *attributes)
{
  VEC(lm_info_p) **list = user_data;
  struct lm_info *last = VEC_last (lm_info_p, *list);
  ULONGEST *address_p = VEC_index (gdb_xml_value_s, attributes, 0)->value;
  CORE_ADDR address = (CORE_ADDR) *address_p;

  if (last->segment_bases != NULL)
    gdb_xml_error (parser,
		   _("Library list with both segments and sections"));

  VEC_safe_push (CORE_ADDR, last->section_bases, &address);
}

/* Handle the start of a <library> element.  */

static void
library_list_start_library (struct gdb_xml_parser *parser,
			    const struct gdb_xml_element *element,
			    void *user_data, VEC(gdb_xml_value_s) *attributes)
{
  VEC(lm_info_p) **list = user_data;
  struct lm_info *item = XZALLOC (struct lm_info);
  const char *name = VEC_index (gdb_xml_value_s, attributes, 0)->value;

  item->name = xstrdup (name);
  VEC_safe_push (lm_info_p, *list, item);
}

static void
library_list_end_library (struct gdb_xml_parser *parser,
			  const struct gdb_xml_element *element,
			  void *user_data, const char *body_text)
{
  VEC(lm_info_p) **list = user_data;
  struct lm_info *lm_info = VEC_last (lm_info_p, *list);
  if (lm_info->segment_bases == NULL
      && lm_info->section_bases == NULL)
    gdb_xml_error (parser,
		   _("No segment or section bases defined"));
}


/* Handle the start of a <library-list> element.  */

static void
library_list_start_list (struct gdb_xml_parser *parser,
			 const struct gdb_xml_element *element,
			 void *user_data, VEC(gdb_xml_value_s) *attributes)
{
  char *version = VEC_index (gdb_xml_value_s, attributes, 0)->value;

  if (strcmp (version, "1.0") != 0)
    gdb_xml_error (parser,
		   _("Library list has unsupported version \"%s\""),
		   version);
}

/* Discard the constructed library list.  */

static void
solib_target_free_library_list (void *p)
{
  VEC(lm_info_p) **result = p;
  struct lm_info *info;
  int ix;

  for (ix = 0; VEC_iterate (lm_info_p, *result, ix, info); ix++)
    {
      xfree (info->name);
      VEC_free (CORE_ADDR, info->segment_bases);
      VEC_free (CORE_ADDR, info->section_bases);
      xfree (info);
    }
  VEC_free (lm_info_p, *result);
  *result = NULL;
}

/* The allowed elements and attributes for an XML library list.
   The root element is a <library-list>.  */

const struct gdb_xml_attribute segment_attributes[] = {
  { "address", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
  { NULL, GDB_XML_AF_NONE, NULL, NULL }
};

const struct gdb_xml_attribute section_attributes[] = {
  { "address", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
  { NULL, GDB_XML_AF_NONE, NULL, NULL }
};

const struct gdb_xml_element library_children[] = {
  { "segment", segment_attributes, NULL,
    GDB_XML_EF_REPEATABLE | GDB_XML_EF_OPTIONAL,
    library_list_start_segment, NULL },
  { "section", section_attributes, NULL,
    GDB_XML_EF_REPEATABLE | GDB_XML_EF_OPTIONAL,
    library_list_start_section, NULL },
  { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
};

const struct gdb_xml_attribute library_attributes[] = {
  { "name", GDB_XML_AF_NONE, NULL, NULL },
  { NULL, GDB_XML_AF_NONE, NULL, NULL }
};

const struct gdb_xml_element library_list_children[] = {
  { "library", library_attributes, library_children,
    GDB_XML_EF_REPEATABLE | GDB_XML_EF_OPTIONAL,
    library_list_start_library, library_list_end_library },
  { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
};

const struct gdb_xml_attribute library_list_attributes[] = {
  { "version", GDB_XML_AF_NONE, NULL, NULL },
  { NULL, GDB_XML_AF_NONE, NULL, NULL }
};

const struct gdb_xml_element library_list_elements[] = {
  { "library-list", library_list_attributes, library_list_children,
    GDB_XML_EF_NONE, library_list_start_list, NULL },
  { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
};

static VEC(lm_info_p) *
solib_target_parse_libraries (const char *library)
{
  struct gdb_xml_parser *parser;
  VEC(lm_info_p) *result = NULL;
  struct cleanup *before_deleting_result, *back_to;

  back_to = make_cleanup (null_cleanup, NULL);
  parser = gdb_xml_create_parser_and_cleanup (_("target library list"),
					      library_list_elements, &result);
  gdb_xml_use_dtd (parser, "library-list.dtd");

  before_deleting_result = make_cleanup (solib_target_free_library_list,
					 &result);

  if (gdb_xml_parse (parser, library) == 0)
    /* Parsed successfully, don't need to delete the result.  */
    discard_cleanups (before_deleting_result);

  do_cleanups (back_to);
  return result;
}
#endif

static struct so_list *
solib_target_current_sos (void)
{
  struct so_list *new_solib, *start = NULL, *last = NULL;
  const char *library_document;
  VEC(lm_info_p) *library_list;
  struct lm_info *info;
  int ix;

  /* Fetch the list of shared libraries.  */
  library_document = target_read_stralloc (&current_target,
					   TARGET_OBJECT_LIBRARIES,
					   NULL);
  if (library_document == NULL)
    return NULL;

  /* Parse the list.  */
  library_list = solib_target_parse_libraries (library_document);
  if (library_list == NULL)
    return NULL;

  /* Build a struct so_list for each entry on the list.  */
  for (ix = 0; VEC_iterate (lm_info_p, library_list, ix, info); ix++)
    {
      new_solib = XZALLOC (struct so_list);
      strncpy (new_solib->so_name, info->name, SO_NAME_MAX_PATH_SIZE - 1);
      new_solib->so_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0';
      strncpy (new_solib->so_original_name, info->name,
	       SO_NAME_MAX_PATH_SIZE - 1);
      new_solib->so_original_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0';
      new_solib->lm_info = info;

      /* We no longer need this copy of the name.  */
      xfree (info->name);
      info->name = NULL;

      /* Add it to the list.  */
      if (!start)
	last = start = new_solib;
      else
	{
	  last->next = new_solib;
	  last = new_solib;
	}
    }

  /* Free the library list, but not its members.  */
  VEC_free (lm_info_p, library_list);

  return start;
}

static void
solib_target_special_symbol_handling (void)
{
  /* Nothing needed.  */
}

static void
solib_target_solib_create_inferior_hook (void)
{
  /* Nothing needed.  */
}

static void
solib_target_clear_solib (void)
{
  /* Nothing needed.  */
}

static void
solib_target_free_so (struct so_list *so)
{
  gdb_assert (so->lm_info->name == NULL);
  xfree (so->lm_info->offsets);
  VEC_free (CORE_ADDR, so->lm_info->segment_bases);
  xfree (so->lm_info);
}

static void
solib_target_relocate_section_addresses (struct so_list *so,
					 struct target_section *sec)
{
  int flags = bfd_get_section_flags (sec->bfd, sec->the_bfd_section);
  CORE_ADDR offset;

  /* Build the offset table only once per object file.  We can not do
     it any earlier, since we need to open the file first.  */
  if (so->lm_info->offsets == NULL)
    {
      int num_sections = bfd_count_sections (so->abfd);

      so->lm_info->offsets = xzalloc (SIZEOF_N_SECTION_OFFSETS (num_sections));

      if (so->lm_info->section_bases)
	{
	  int i;
	  asection *sect;
	  int num_section_bases
	    = VEC_length (CORE_ADDR, so->lm_info->section_bases);
	  int num_alloc_sections = 0;

	  for (i = 0, sect = so->abfd->sections;
	       sect != NULL;
	       i++, sect = sect->next)
	    if ((bfd_get_section_flags (so->abfd, sect) & SEC_ALLOC))
	      num_alloc_sections++;

	  if (num_alloc_sections != num_section_bases)
	    warning (_("\
Could not relocate shared library \"%s\": wrong number of ALLOC sections"),
		     so->so_name);
	  else
	    {
	      int bases_index = 0;
	      int found_range = 0;
	      CORE_ADDR *section_bases;
	      section_bases = VEC_address (CORE_ADDR,
					   so->lm_info->section_bases);

	      so->addr_low = ~(CORE_ADDR) 0;
	      so->addr_high = 0;
	      for (i = 0, sect = so->abfd->sections;
		   sect != NULL;
		   i++, sect = sect->next)
		{
		  if (!(bfd_get_section_flags (so->abfd, sect) & SEC_ALLOC))
		    continue;
		  if (bfd_section_size (so->abfd, sect) > 0)
		    {
		      CORE_ADDR low, high;
		      low = section_bases[i];
		      high = low + bfd_section_size (so->abfd, sect) - 1;

		      if (low < so->addr_low)
			so->addr_low = low;
		      if (high > so->addr_high)
			so->addr_high = high;
		      gdb_assert (so->addr_low <= so->addr_high);
		      found_range = 1;
		    }
		  so->lm_info->offsets->offsets[i] = section_bases[bases_index];
		  bases_index++;
		}
	      if (!found_range)
		so->addr_low = so->addr_high = 0;
	      gdb_assert (so->addr_low <= so->addr_high);
	    }
	}
      else if (so->lm_info->segment_bases)
	{
	  struct symfile_segment_data *data;
	  data = get_symfile_segment_data (so->abfd);
	  if (data == NULL)
	    warning (_("\
Could not relocate shared library \"%s\": no segments"), so->so_name);
	  else
	    {
	      ULONGEST orig_delta;
	      int i;
	      int num_bases;
	      CORE_ADDR *segment_bases;

	      num_bases = VEC_length (CORE_ADDR, so->lm_info->segment_bases);
	      segment_bases = VEC_address (CORE_ADDR,
					   so->lm_info->segment_bases);

	      if (!symfile_map_offsets_to_segments (so->abfd, data,
						    so->lm_info->offsets,
						    num_bases, segment_bases))
		warning (_("\
Could not relocate shared library \"%s\": bad offsets"), so->so_name);

	      /* Find the range of addresses to report for this library in
		 "info sharedlibrary".  Report any consecutive segments
		 which were relocated as a single unit.  */
	      gdb_assert (num_bases > 0);
	      orig_delta = segment_bases[0] - data->segment_bases[0];

	      for (i = 1; i < data->num_segments; i++)
		{
		  /* If we have run out of offsets, assume all
		     remaining segments have the same offset.  */
		  if (i >= num_bases)
		    continue;

		  /* If this segment does not have the same offset, do
		     not include it in the library's range.  */
		  if (segment_bases[i] - data->segment_bases[i] != orig_delta)
		    break;
		}

	      so->addr_low = segment_bases[0];
	      so->addr_high = (data->segment_bases[i - 1]
			       + data->segment_sizes[i - 1]
			       + orig_delta);
	      gdb_assert (so->addr_low <= so->addr_high);

	      free_symfile_segment_data (data);
	    }
	}
    }

  offset = so->lm_info->offsets->offsets[sec->the_bfd_section->index];
  sec->addr += offset;
  sec->endaddr += offset;
}

static int
solib_target_open_symbol_file_object (void *from_ttyp)
{
  /* We can't locate the main symbol file based on the target's
     knowledge; the user has to specify it.  */
  return 0;
}

static int
solib_target_in_dynsym_resolve_code (CORE_ADDR pc)
{
  /* We don't have a range of addresses for the dynamic linker; there
     may not be one in the program's address space.  So only report
     PLT entries (which may be import stubs).  */
  return in_plt_section (pc, NULL);
}

struct target_so_ops solib_target_so_ops;

extern initialize_file_ftype _initialize_solib_target; /* -Wmissing-prototypes */

void
_initialize_solib_target (void)
{
  solib_target_so_ops.relocate_section_addresses
    = solib_target_relocate_section_addresses;
  solib_target_so_ops.free_so = solib_target_free_so;
  solib_target_so_ops.clear_solib = solib_target_clear_solib;
  solib_target_so_ops.solib_create_inferior_hook
    = solib_target_solib_create_inferior_hook;
  solib_target_so_ops.special_symbol_handling
    = solib_target_special_symbol_handling;
  solib_target_so_ops.current_sos = solib_target_current_sos;
  solib_target_so_ops.open_symbol_file_object
    = solib_target_open_symbol_file_object;
  solib_target_so_ops.in_dynsym_resolve_code
    = solib_target_in_dynsym_resolve_code;
  solib_target_so_ops.bfd_open = solib_bfd_open;
}
