OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gdb-7.1/] [gdb/] [solib-target.c] - Diff between revs 834 and 842

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 834 Rev 842
/* Definitions for targets which report shared library events.
/* Definitions for targets which report shared library events.
 
 
   Copyright (C) 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
   Copyright (C) 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
 
 
   This file is part of GDB.
   This file is part of GDB.
 
 
   This program is free software; you can redistribute it and/or modify
   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
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.
   (at your option) any later version.
 
 
   This program is distributed in the hope that it will be useful,
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
   GNU General Public License for more details.
 
 
   You should have received a copy of the GNU General Public License
   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 
#include "defs.h"
#include "defs.h"
#include "objfiles.h"
#include "objfiles.h"
#include "solist.h"
#include "solist.h"
#include "symtab.h"
#include "symtab.h"
#include "symfile.h"
#include "symfile.h"
#include "target.h"
#include "target.h"
#include "vec.h"
#include "vec.h"
#include "solib-target.h"
#include "solib-target.h"
 
 
#include "gdb_string.h"
#include "gdb_string.h"
 
 
DEF_VEC_O(CORE_ADDR);
DEF_VEC_O(CORE_ADDR);
 
 
/* Private data for each loaded library.  */
/* Private data for each loaded library.  */
struct lm_info
struct lm_info
{
{
  /* The library's name.  The name is normally kept in the struct
  /* The library's name.  The name is normally kept in the struct
     so_list; it is only here during XML parsing.  */
     so_list; it is only here during XML parsing.  */
  char *name;
  char *name;
 
 
  /* The target can either specify segment bases or section bases, not
  /* The target can either specify segment bases or section bases, not
     both.  */
     both.  */
 
 
  /* The base addresses for each independently relocatable segment of
  /* The base addresses for each independently relocatable segment of
     this shared library.  */
     this shared library.  */
  VEC(CORE_ADDR) *segment_bases;
  VEC(CORE_ADDR) *segment_bases;
 
 
  /* The base addresses for each independently allocatable,
  /* The base addresses for each independently allocatable,
     relocatable section of this shared library.  */
     relocatable section of this shared library.  */
  VEC(CORE_ADDR) *section_bases;
  VEC(CORE_ADDR) *section_bases;
 
 
  /* The cached offsets for each section of this shared library,
  /* The cached offsets for each section of this shared library,
     determined from SEGMENT_BASES, or SECTION_BASES.  */
     determined from SEGMENT_BASES, or SECTION_BASES.  */
  struct section_offsets *offsets;
  struct section_offsets *offsets;
};
};
 
 
typedef struct lm_info *lm_info_p;
typedef struct lm_info *lm_info_p;
DEF_VEC_P(lm_info_p);
DEF_VEC_P(lm_info_p);
 
 
#if !defined(HAVE_LIBEXPAT)
#if !defined(HAVE_LIBEXPAT)
 
 
static VEC(lm_info_p) *
static VEC(lm_info_p) *
solib_target_parse_libraries (const char *library)
solib_target_parse_libraries (const char *library)
{
{
  static int have_warned;
  static int have_warned;
 
 
  if (!have_warned)
  if (!have_warned)
    {
    {
      have_warned = 1;
      have_warned = 1;
      warning (_("Can not parse XML library list; XML support was disabled "
      warning (_("Can not parse XML library list; XML support was disabled "
                 "at compile time"));
                 "at compile time"));
    }
    }
 
 
  return NULL;
  return NULL;
}
}
 
 
#else /* HAVE_LIBEXPAT */
#else /* HAVE_LIBEXPAT */
 
 
#include "xml-support.h"
#include "xml-support.h"
 
 
/* Handle the start of a <segment> element.  */
/* Handle the start of a <segment> element.  */
 
 
static void
static void
library_list_start_segment (struct gdb_xml_parser *parser,
library_list_start_segment (struct gdb_xml_parser *parser,
                            const struct gdb_xml_element *element,
                            const struct gdb_xml_element *element,
                            void *user_data, VEC(gdb_xml_value_s) *attributes)
                            void *user_data, VEC(gdb_xml_value_s) *attributes)
{
{
  VEC(lm_info_p) **list = user_data;
  VEC(lm_info_p) **list = user_data;
  struct lm_info *last = VEC_last (lm_info_p, *list);
  struct lm_info *last = VEC_last (lm_info_p, *list);
  ULONGEST *address_p = VEC_index (gdb_xml_value_s, attributes, 0)->value;
  ULONGEST *address_p = VEC_index (gdb_xml_value_s, attributes, 0)->value;
  CORE_ADDR address = (CORE_ADDR) *address_p;
  CORE_ADDR address = (CORE_ADDR) *address_p;
 
 
  if (last->section_bases != NULL)
  if (last->section_bases != NULL)
    gdb_xml_error (parser,
    gdb_xml_error (parser,
                   _("Library list with both segments and sections"));
                   _("Library list with both segments and sections"));
 
 
  VEC_safe_push (CORE_ADDR, last->segment_bases, &address);
  VEC_safe_push (CORE_ADDR, last->segment_bases, &address);
}
}
 
 
static void
static void
library_list_start_section (struct gdb_xml_parser *parser,
library_list_start_section (struct gdb_xml_parser *parser,
                            const struct gdb_xml_element *element,
                            const struct gdb_xml_element *element,
                            void *user_data, VEC(gdb_xml_value_s) *attributes)
                            void *user_data, VEC(gdb_xml_value_s) *attributes)
{
{
  VEC(lm_info_p) **list = user_data;
  VEC(lm_info_p) **list = user_data;
  struct lm_info *last = VEC_last (lm_info_p, *list);
  struct lm_info *last = VEC_last (lm_info_p, *list);
  ULONGEST *address_p = VEC_index (gdb_xml_value_s, attributes, 0)->value;
  ULONGEST *address_p = VEC_index (gdb_xml_value_s, attributes, 0)->value;
  CORE_ADDR address = (CORE_ADDR) *address_p;
  CORE_ADDR address = (CORE_ADDR) *address_p;
 
 
  if (last->segment_bases != NULL)
  if (last->segment_bases != NULL)
    gdb_xml_error (parser,
    gdb_xml_error (parser,
                   _("Library list with both segments and sections"));
                   _("Library list with both segments and sections"));
 
 
  VEC_safe_push (CORE_ADDR, last->section_bases, &address);
  VEC_safe_push (CORE_ADDR, last->section_bases, &address);
}
}
 
 
/* Handle the start of a <library> element.  */
/* Handle the start of a <library> element.  */
 
 
static void
static void
library_list_start_library (struct gdb_xml_parser *parser,
library_list_start_library (struct gdb_xml_parser *parser,
                            const struct gdb_xml_element *element,
                            const struct gdb_xml_element *element,
                            void *user_data, VEC(gdb_xml_value_s) *attributes)
                            void *user_data, VEC(gdb_xml_value_s) *attributes)
{
{
  VEC(lm_info_p) **list = user_data;
  VEC(lm_info_p) **list = user_data;
  struct lm_info *item = XZALLOC (struct lm_info);
  struct lm_info *item = XZALLOC (struct lm_info);
  const char *name = VEC_index (gdb_xml_value_s, attributes, 0)->value;
  const char *name = VEC_index (gdb_xml_value_s, attributes, 0)->value;
 
 
  item->name = xstrdup (name);
  item->name = xstrdup (name);
  VEC_safe_push (lm_info_p, *list, item);
  VEC_safe_push (lm_info_p, *list, item);
}
}
 
 
static void
static void
library_list_end_library (struct gdb_xml_parser *parser,
library_list_end_library (struct gdb_xml_parser *parser,
                          const struct gdb_xml_element *element,
                          const struct gdb_xml_element *element,
                          void *user_data, const char *body_text)
                          void *user_data, const char *body_text)
{
{
  VEC(lm_info_p) **list = user_data;
  VEC(lm_info_p) **list = user_data;
  struct lm_info *lm_info = VEC_last (lm_info_p, *list);
  struct lm_info *lm_info = VEC_last (lm_info_p, *list);
  if (lm_info->segment_bases == NULL
  if (lm_info->segment_bases == NULL
      && lm_info->section_bases == NULL)
      && lm_info->section_bases == NULL)
    gdb_xml_error (parser,
    gdb_xml_error (parser,
                   _("No segment or section bases defined"));
                   _("No segment or section bases defined"));
}
}
 
 
 
 
/* Handle the start of a <library-list> element.  */
/* Handle the start of a <library-list> element.  */
 
 
static void
static void
library_list_start_list (struct gdb_xml_parser *parser,
library_list_start_list (struct gdb_xml_parser *parser,
                         const struct gdb_xml_element *element,
                         const struct gdb_xml_element *element,
                         void *user_data, VEC(gdb_xml_value_s) *attributes)
                         void *user_data, VEC(gdb_xml_value_s) *attributes)
{
{
  char *version = VEC_index (gdb_xml_value_s, attributes, 0)->value;
  char *version = VEC_index (gdb_xml_value_s, attributes, 0)->value;
 
 
  if (strcmp (version, "1.0") != 0)
  if (strcmp (version, "1.0") != 0)
    gdb_xml_error (parser,
    gdb_xml_error (parser,
                   _("Library list has unsupported version \"%s\""),
                   _("Library list has unsupported version \"%s\""),
                   version);
                   version);
}
}
 
 
/* Discard the constructed library list.  */
/* Discard the constructed library list.  */
 
 
static void
static void
solib_target_free_library_list (void *p)
solib_target_free_library_list (void *p)
{
{
  VEC(lm_info_p) **result = p;
  VEC(lm_info_p) **result = p;
  struct lm_info *info;
  struct lm_info *info;
  int ix;
  int ix;
 
 
  for (ix = 0; VEC_iterate (lm_info_p, *result, ix, info); ix++)
  for (ix = 0; VEC_iterate (lm_info_p, *result, ix, info); ix++)
    {
    {
      xfree (info->name);
      xfree (info->name);
      VEC_free (CORE_ADDR, info->segment_bases);
      VEC_free (CORE_ADDR, info->segment_bases);
      VEC_free (CORE_ADDR, info->section_bases);
      VEC_free (CORE_ADDR, info->section_bases);
      xfree (info);
      xfree (info);
    }
    }
  VEC_free (lm_info_p, *result);
  VEC_free (lm_info_p, *result);
  *result = NULL;
  *result = NULL;
}
}
 
 
/* The allowed elements and attributes for an XML library list.
/* The allowed elements and attributes for an XML library list.
   The root element is a <library-list>.  */
   The root element is a <library-list>.  */
 
 
const struct gdb_xml_attribute segment_attributes[] = {
const struct gdb_xml_attribute segment_attributes[] = {
  { "address", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
  { "address", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
  { NULL, GDB_XML_AF_NONE, NULL, NULL }
  { NULL, GDB_XML_AF_NONE, NULL, NULL }
};
};
 
 
const struct gdb_xml_attribute section_attributes[] = {
const struct gdb_xml_attribute section_attributes[] = {
  { "address", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
  { "address", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
  { NULL, GDB_XML_AF_NONE, NULL, NULL }
  { NULL, GDB_XML_AF_NONE, NULL, NULL }
};
};
 
 
const struct gdb_xml_element library_children[] = {
const struct gdb_xml_element library_children[] = {
  { "segment", segment_attributes, NULL,
  { "segment", segment_attributes, NULL,
    GDB_XML_EF_REPEATABLE | GDB_XML_EF_OPTIONAL,
    GDB_XML_EF_REPEATABLE | GDB_XML_EF_OPTIONAL,
    library_list_start_segment, NULL },
    library_list_start_segment, NULL },
  { "section", section_attributes, NULL,
  { "section", section_attributes, NULL,
    GDB_XML_EF_REPEATABLE | GDB_XML_EF_OPTIONAL,
    GDB_XML_EF_REPEATABLE | GDB_XML_EF_OPTIONAL,
    library_list_start_section, NULL },
    library_list_start_section, NULL },
  { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
  { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
};
};
 
 
const struct gdb_xml_attribute library_attributes[] = {
const struct gdb_xml_attribute library_attributes[] = {
  { "name", GDB_XML_AF_NONE, NULL, NULL },
  { "name", GDB_XML_AF_NONE, NULL, NULL },
  { NULL, GDB_XML_AF_NONE, NULL, NULL }
  { NULL, GDB_XML_AF_NONE, NULL, NULL }
};
};
 
 
const struct gdb_xml_element library_list_children[] = {
const struct gdb_xml_element library_list_children[] = {
  { "library", library_attributes, library_children,
  { "library", library_attributes, library_children,
    GDB_XML_EF_REPEATABLE | GDB_XML_EF_OPTIONAL,
    GDB_XML_EF_REPEATABLE | GDB_XML_EF_OPTIONAL,
    library_list_start_library, library_list_end_library },
    library_list_start_library, library_list_end_library },
  { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
  { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
};
};
 
 
const struct gdb_xml_attribute library_list_attributes[] = {
const struct gdb_xml_attribute library_list_attributes[] = {
  { "version", GDB_XML_AF_NONE, NULL, NULL },
  { "version", GDB_XML_AF_NONE, NULL, NULL },
  { NULL, GDB_XML_AF_NONE, NULL, NULL }
  { NULL, GDB_XML_AF_NONE, NULL, NULL }
};
};
 
 
const struct gdb_xml_element library_list_elements[] = {
const struct gdb_xml_element library_list_elements[] = {
  { "library-list", library_list_attributes, library_list_children,
  { "library-list", library_list_attributes, library_list_children,
    GDB_XML_EF_NONE, library_list_start_list, NULL },
    GDB_XML_EF_NONE, library_list_start_list, NULL },
  { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
  { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
};
};
 
 
static VEC(lm_info_p) *
static VEC(lm_info_p) *
solib_target_parse_libraries (const char *library)
solib_target_parse_libraries (const char *library)
{
{
  struct gdb_xml_parser *parser;
  struct gdb_xml_parser *parser;
  VEC(lm_info_p) *result = NULL;
  VEC(lm_info_p) *result = NULL;
  struct cleanup *before_deleting_result, *back_to;
  struct cleanup *before_deleting_result, *back_to;
 
 
  back_to = make_cleanup (null_cleanup, NULL);
  back_to = make_cleanup (null_cleanup, NULL);
  parser = gdb_xml_create_parser_and_cleanup (_("target library list"),
  parser = gdb_xml_create_parser_and_cleanup (_("target library list"),
                                              library_list_elements, &result);
                                              library_list_elements, &result);
  gdb_xml_use_dtd (parser, "library-list.dtd");
  gdb_xml_use_dtd (parser, "library-list.dtd");
 
 
  before_deleting_result = make_cleanup (solib_target_free_library_list,
  before_deleting_result = make_cleanup (solib_target_free_library_list,
                                         &result);
                                         &result);
 
 
  if (gdb_xml_parse (parser, library) == 0)
  if (gdb_xml_parse (parser, library) == 0)
    /* Parsed successfully, don't need to delete the result.  */
    /* Parsed successfully, don't need to delete the result.  */
    discard_cleanups (before_deleting_result);
    discard_cleanups (before_deleting_result);
 
 
  do_cleanups (back_to);
  do_cleanups (back_to);
  return result;
  return result;
}
}
#endif
#endif
 
 
static struct so_list *
static struct so_list *
solib_target_current_sos (void)
solib_target_current_sos (void)
{
{
  struct so_list *new_solib, *start = NULL, *last = NULL;
  struct so_list *new_solib, *start = NULL, *last = NULL;
  const char *library_document;
  const char *library_document;
  VEC(lm_info_p) *library_list;
  VEC(lm_info_p) *library_list;
  struct lm_info *info;
  struct lm_info *info;
  int ix;
  int ix;
 
 
  /* Fetch the list of shared libraries.  */
  /* Fetch the list of shared libraries.  */
  library_document = target_read_stralloc (&current_target,
  library_document = target_read_stralloc (&current_target,
                                           TARGET_OBJECT_LIBRARIES,
                                           TARGET_OBJECT_LIBRARIES,
                                           NULL);
                                           NULL);
  if (library_document == NULL)
  if (library_document == NULL)
    return NULL;
    return NULL;
 
 
  /* Parse the list.  */
  /* Parse the list.  */
  library_list = solib_target_parse_libraries (library_document);
  library_list = solib_target_parse_libraries (library_document);
  if (library_list == NULL)
  if (library_list == NULL)
    return NULL;
    return NULL;
 
 
  /* Build a struct so_list for each entry on the list.  */
  /* Build a struct so_list for each entry on the list.  */
  for (ix = 0; VEC_iterate (lm_info_p, library_list, ix, info); ix++)
  for (ix = 0; VEC_iterate (lm_info_p, library_list, ix, info); ix++)
    {
    {
      new_solib = XZALLOC (struct so_list);
      new_solib = XZALLOC (struct so_list);
      strncpy (new_solib->so_name, info->name, SO_NAME_MAX_PATH_SIZE - 1);
      strncpy (new_solib->so_name, info->name, SO_NAME_MAX_PATH_SIZE - 1);
      new_solib->so_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0';
      new_solib->so_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0';
      strncpy (new_solib->so_original_name, info->name,
      strncpy (new_solib->so_original_name, info->name,
               SO_NAME_MAX_PATH_SIZE - 1);
               SO_NAME_MAX_PATH_SIZE - 1);
      new_solib->so_original_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0';
      new_solib->so_original_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0';
      new_solib->lm_info = info;
      new_solib->lm_info = info;
 
 
      /* We no longer need this copy of the name.  */
      /* We no longer need this copy of the name.  */
      xfree (info->name);
      xfree (info->name);
      info->name = NULL;
      info->name = NULL;
 
 
      /* Add it to the list.  */
      /* Add it to the list.  */
      if (!start)
      if (!start)
        last = start = new_solib;
        last = start = new_solib;
      else
      else
        {
        {
          last->next = new_solib;
          last->next = new_solib;
          last = new_solib;
          last = new_solib;
        }
        }
    }
    }
 
 
  /* Free the library list, but not its members.  */
  /* Free the library list, but not its members.  */
  VEC_free (lm_info_p, library_list);
  VEC_free (lm_info_p, library_list);
 
 
  return start;
  return start;
}
}
 
 
static void
static void
solib_target_special_symbol_handling (void)
solib_target_special_symbol_handling (void)
{
{
  /* Nothing needed.  */
  /* Nothing needed.  */
}
}
 
 
static void
static void
solib_target_solib_create_inferior_hook (int from_tty)
solib_target_solib_create_inferior_hook (int from_tty)
{
{
  /* Nothing needed.  */
  /* Nothing needed.  */
}
}
 
 
static void
static void
solib_target_clear_solib (void)
solib_target_clear_solib (void)
{
{
  /* Nothing needed.  */
  /* Nothing needed.  */
}
}
 
 
static void
static void
solib_target_free_so (struct so_list *so)
solib_target_free_so (struct so_list *so)
{
{
  gdb_assert (so->lm_info->name == NULL);
  gdb_assert (so->lm_info->name == NULL);
  xfree (so->lm_info->offsets);
  xfree (so->lm_info->offsets);
  VEC_free (CORE_ADDR, so->lm_info->segment_bases);
  VEC_free (CORE_ADDR, so->lm_info->segment_bases);
  xfree (so->lm_info);
  xfree (so->lm_info);
}
}
 
 
static void
static void
solib_target_relocate_section_addresses (struct so_list *so,
solib_target_relocate_section_addresses (struct so_list *so,
                                         struct target_section *sec)
                                         struct target_section *sec)
{
{
  int flags = bfd_get_section_flags (sec->bfd, sec->the_bfd_section);
  int flags = bfd_get_section_flags (sec->bfd, sec->the_bfd_section);
  CORE_ADDR offset;
  CORE_ADDR offset;
 
 
  /* Build the offset table only once per object file.  We can not do
  /* Build the offset table only once per object file.  We can not do
     it any earlier, since we need to open the file first.  */
     it any earlier, since we need to open the file first.  */
  if (so->lm_info->offsets == NULL)
  if (so->lm_info->offsets == NULL)
    {
    {
      int num_sections = bfd_count_sections (so->abfd);
      int num_sections = bfd_count_sections (so->abfd);
 
 
      so->lm_info->offsets = xzalloc (SIZEOF_N_SECTION_OFFSETS (num_sections));
      so->lm_info->offsets = xzalloc (SIZEOF_N_SECTION_OFFSETS (num_sections));
 
 
      if (so->lm_info->section_bases)
      if (so->lm_info->section_bases)
        {
        {
          int i;
          int i;
          asection *sect;
          asection *sect;
          int num_section_bases
          int num_section_bases
            = VEC_length (CORE_ADDR, so->lm_info->section_bases);
            = VEC_length (CORE_ADDR, so->lm_info->section_bases);
          int num_alloc_sections = 0;
          int num_alloc_sections = 0;
 
 
          for (i = 0, sect = so->abfd->sections;
          for (i = 0, sect = so->abfd->sections;
               sect != NULL;
               sect != NULL;
               i++, sect = sect->next)
               i++, sect = sect->next)
            if ((bfd_get_section_flags (so->abfd, sect) & SEC_ALLOC))
            if ((bfd_get_section_flags (so->abfd, sect) & SEC_ALLOC))
              num_alloc_sections++;
              num_alloc_sections++;
 
 
          if (num_alloc_sections != num_section_bases)
          if (num_alloc_sections != num_section_bases)
            warning (_("\
            warning (_("\
Could not relocate shared library \"%s\": wrong number of ALLOC sections"),
Could not relocate shared library \"%s\": wrong number of ALLOC sections"),
                     so->so_name);
                     so->so_name);
          else
          else
            {
            {
              int bases_index = 0;
              int bases_index = 0;
              int found_range = 0;
              int found_range = 0;
              CORE_ADDR *section_bases;
              CORE_ADDR *section_bases;
              section_bases = VEC_address (CORE_ADDR,
              section_bases = VEC_address (CORE_ADDR,
                                           so->lm_info->section_bases);
                                           so->lm_info->section_bases);
 
 
              so->addr_low = ~(CORE_ADDR) 0;
              so->addr_low = ~(CORE_ADDR) 0;
              so->addr_high = 0;
              so->addr_high = 0;
              for (i = 0, sect = so->abfd->sections;
              for (i = 0, sect = so->abfd->sections;
                   sect != NULL;
                   sect != NULL;
                   i++, sect = sect->next)
                   i++, sect = sect->next)
                {
                {
                  if (!(bfd_get_section_flags (so->abfd, sect) & SEC_ALLOC))
                  if (!(bfd_get_section_flags (so->abfd, sect) & SEC_ALLOC))
                    continue;
                    continue;
                  if (bfd_section_size (so->abfd, sect) > 0)
                  if (bfd_section_size (so->abfd, sect) > 0)
                    {
                    {
                      CORE_ADDR low, high;
                      CORE_ADDR low, high;
                      low = section_bases[i];
                      low = section_bases[i];
                      high = low + bfd_section_size (so->abfd, sect) - 1;
                      high = low + bfd_section_size (so->abfd, sect) - 1;
 
 
                      if (low < so->addr_low)
                      if (low < so->addr_low)
                        so->addr_low = low;
                        so->addr_low = low;
                      if (high > so->addr_high)
                      if (high > so->addr_high)
                        so->addr_high = high;
                        so->addr_high = high;
                      gdb_assert (so->addr_low <= so->addr_high);
                      gdb_assert (so->addr_low <= so->addr_high);
                      found_range = 1;
                      found_range = 1;
                    }
                    }
                  so->lm_info->offsets->offsets[i] = section_bases[bases_index];
                  so->lm_info->offsets->offsets[i] = section_bases[bases_index];
                  bases_index++;
                  bases_index++;
                }
                }
              if (!found_range)
              if (!found_range)
                so->addr_low = so->addr_high = 0;
                so->addr_low = so->addr_high = 0;
              gdb_assert (so->addr_low <= so->addr_high);
              gdb_assert (so->addr_low <= so->addr_high);
            }
            }
        }
        }
      else if (so->lm_info->segment_bases)
      else if (so->lm_info->segment_bases)
        {
        {
          struct symfile_segment_data *data;
          struct symfile_segment_data *data;
          data = get_symfile_segment_data (so->abfd);
          data = get_symfile_segment_data (so->abfd);
          if (data == NULL)
          if (data == NULL)
            warning (_("\
            warning (_("\
Could not relocate shared library \"%s\": no segments"), so->so_name);
Could not relocate shared library \"%s\": no segments"), so->so_name);
          else
          else
            {
            {
              ULONGEST orig_delta;
              ULONGEST orig_delta;
              int i;
              int i;
              int num_bases;
              int num_bases;
              CORE_ADDR *segment_bases;
              CORE_ADDR *segment_bases;
 
 
              num_bases = VEC_length (CORE_ADDR, so->lm_info->segment_bases);
              num_bases = VEC_length (CORE_ADDR, so->lm_info->segment_bases);
              segment_bases = VEC_address (CORE_ADDR,
              segment_bases = VEC_address (CORE_ADDR,
                                           so->lm_info->segment_bases);
                                           so->lm_info->segment_bases);
 
 
              if (!symfile_map_offsets_to_segments (so->abfd, data,
              if (!symfile_map_offsets_to_segments (so->abfd, data,
                                                    so->lm_info->offsets,
                                                    so->lm_info->offsets,
                                                    num_bases, segment_bases))
                                                    num_bases, segment_bases))
                warning (_("\
                warning (_("\
Could not relocate shared library \"%s\": bad offsets"), so->so_name);
Could not relocate shared library \"%s\": bad offsets"), so->so_name);
 
 
              /* Find the range of addresses to report for this library in
              /* Find the range of addresses to report for this library in
                 "info sharedlibrary".  Report any consecutive segments
                 "info sharedlibrary".  Report any consecutive segments
                 which were relocated as a single unit.  */
                 which were relocated as a single unit.  */
              gdb_assert (num_bases > 0);
              gdb_assert (num_bases > 0);
              orig_delta = segment_bases[0] - data->segment_bases[0];
              orig_delta = segment_bases[0] - data->segment_bases[0];
 
 
              for (i = 1; i < data->num_segments; i++)
              for (i = 1; i < data->num_segments; i++)
                {
                {
                  /* If we have run out of offsets, assume all
                  /* If we have run out of offsets, assume all
                     remaining segments have the same offset.  */
                     remaining segments have the same offset.  */
                  if (i >= num_bases)
                  if (i >= num_bases)
                    continue;
                    continue;
 
 
                  /* If this segment does not have the same offset, do
                  /* If this segment does not have the same offset, do
                     not include it in the library's range.  */
                     not include it in the library's range.  */
                  if (segment_bases[i] - data->segment_bases[i] != orig_delta)
                  if (segment_bases[i] - data->segment_bases[i] != orig_delta)
                    break;
                    break;
                }
                }
 
 
              so->addr_low = segment_bases[0];
              so->addr_low = segment_bases[0];
              so->addr_high = (data->segment_bases[i - 1]
              so->addr_high = (data->segment_bases[i - 1]
                               + data->segment_sizes[i - 1]
                               + data->segment_sizes[i - 1]
                               + orig_delta);
                               + orig_delta);
              gdb_assert (so->addr_low <= so->addr_high);
              gdb_assert (so->addr_low <= so->addr_high);
 
 
              free_symfile_segment_data (data);
              free_symfile_segment_data (data);
            }
            }
        }
        }
    }
    }
 
 
  offset = so->lm_info->offsets->offsets[sec->the_bfd_section->index];
  offset = so->lm_info->offsets->offsets[sec->the_bfd_section->index];
  sec->addr += offset;
  sec->addr += offset;
  sec->endaddr += offset;
  sec->endaddr += offset;
}
}
 
 
static int
static int
solib_target_open_symbol_file_object (void *from_ttyp)
solib_target_open_symbol_file_object (void *from_ttyp)
{
{
  /* We can't locate the main symbol file based on the target's
  /* We can't locate the main symbol file based on the target's
     knowledge; the user has to specify it.  */
     knowledge; the user has to specify it.  */
  return 0;
  return 0;
}
}
 
 
static int
static int
solib_target_in_dynsym_resolve_code (CORE_ADDR pc)
solib_target_in_dynsym_resolve_code (CORE_ADDR pc)
{
{
  /* We don't have a range of addresses for the dynamic linker; there
  /* 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
     may not be one in the program's address space.  So only report
     PLT entries (which may be import stubs).  */
     PLT entries (which may be import stubs).  */
  return in_plt_section (pc, NULL);
  return in_plt_section (pc, NULL);
}
}
 
 
struct target_so_ops solib_target_so_ops;
struct target_so_ops solib_target_so_ops;
 
 
extern initialize_file_ftype _initialize_solib_target; /* -Wmissing-prototypes */
extern initialize_file_ftype _initialize_solib_target; /* -Wmissing-prototypes */
 
 
void
void
_initialize_solib_target (void)
_initialize_solib_target (void)
{
{
  solib_target_so_ops.relocate_section_addresses
  solib_target_so_ops.relocate_section_addresses
    = solib_target_relocate_section_addresses;
    = solib_target_relocate_section_addresses;
  solib_target_so_ops.free_so = solib_target_free_so;
  solib_target_so_ops.free_so = solib_target_free_so;
  solib_target_so_ops.clear_solib = solib_target_clear_solib;
  solib_target_so_ops.clear_solib = solib_target_clear_solib;
  solib_target_so_ops.solib_create_inferior_hook
  solib_target_so_ops.solib_create_inferior_hook
    = solib_target_solib_create_inferior_hook;
    = solib_target_solib_create_inferior_hook;
  solib_target_so_ops.special_symbol_handling
  solib_target_so_ops.special_symbol_handling
    = solib_target_special_symbol_handling;
    = solib_target_special_symbol_handling;
  solib_target_so_ops.current_sos = solib_target_current_sos;
  solib_target_so_ops.current_sos = solib_target_current_sos;
  solib_target_so_ops.open_symbol_file_object
  solib_target_so_ops.open_symbol_file_object
    = solib_target_open_symbol_file_object;
    = solib_target_open_symbol_file_object;
  solib_target_so_ops.in_dynsym_resolve_code
  solib_target_so_ops.in_dynsym_resolve_code
    = solib_target_in_dynsym_resolve_code;
    = solib_target_in_dynsym_resolve_code;
  solib_target_so_ops.bfd_open = solib_bfd_open;
  solib_target_so_ops.bfd_open = solib_bfd_open;
}
}
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.