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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gdb-7.1/] [gdb/] [xml-syscall.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
/* Functions that provide the mechanism to parse a syscall XML file
/* Functions that provide the mechanism to parse a syscall XML file
   and get its values.
   and get its values.
 
 
   Copyright (C) 2009, 2010 Free Software Foundation, Inc.
   Copyright (C) 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 "gdbtypes.h"
#include "gdbtypes.h"
#include "xml-support.h"
#include "xml-support.h"
#include "xml-syscall.h"
#include "xml-syscall.h"
 
 
/* For the struct syscall definition.  */
/* For the struct syscall definition.  */
#include "target.h"
#include "target.h"
 
 
#include "filenames.h"
#include "filenames.h"
 
 
#include "gdb_assert.h"
#include "gdb_assert.h"
 
 
#ifndef HAVE_LIBEXPAT
#ifndef HAVE_LIBEXPAT
 
 
/* Dummy functions to indicate that there's no support for fetching
/* Dummy functions to indicate that there's no support for fetching
   syscalls information.  */
   syscalls information.  */
 
 
static void
static void
syscall_warn_user (void)
syscall_warn_user (void)
{
{
  static int have_warned = 0;
  static int have_warned = 0;
  if (!have_warned)
  if (!have_warned)
    {
    {
      have_warned = 1;
      have_warned = 1;
      warning (_("Can not parse XML syscalls information; XML support was "
      warning (_("Can not parse XML syscalls information; XML support was "
                 "disabled at compile time."));
                 "disabled at compile time."));
    }
    }
}
}
 
 
void
void
set_xml_syscall_file_name (const char *name)
set_xml_syscall_file_name (const char *name)
{
{
  return;
  return;
}
}
 
 
void
void
get_syscall_by_number (int syscall_number,
get_syscall_by_number (int syscall_number,
                       struct syscall *s)
                       struct syscall *s)
{
{
  syscall_warn_user ();
  syscall_warn_user ();
  s->number = syscall_number;
  s->number = syscall_number;
  s->name = NULL;
  s->name = NULL;
}
}
 
 
void
void
get_syscall_by_name (const char *syscall_name,
get_syscall_by_name (const char *syscall_name,
                     struct syscall *s)
                     struct syscall *s)
{
{
  syscall_warn_user ();
  syscall_warn_user ();
  s->number = UNKNOWN_SYSCALL;
  s->number = UNKNOWN_SYSCALL;
  s->name = syscall_name;
  s->name = syscall_name;
}
}
 
 
const char **
const char **
get_syscall_names (void)
get_syscall_names (void)
{
{
  syscall_warn_user ();
  syscall_warn_user ();
  return NULL;
  return NULL;
}
}
 
 
#else /* ! HAVE_LIBEXPAT */
#else /* ! HAVE_LIBEXPAT */
 
 
/* Structure which describes a syscall.  */
/* Structure which describes a syscall.  */
typedef struct syscall_desc
typedef struct syscall_desc
{
{
  /* The syscall number.  */
  /* The syscall number.  */
 
 
  int number;
  int number;
 
 
  /* The syscall name.  */
  /* The syscall name.  */
 
 
  char *name;
  char *name;
} *syscall_desc_p;
} *syscall_desc_p;
DEF_VEC_P(syscall_desc_p);
DEF_VEC_P(syscall_desc_p);
 
 
/* Structure that represents syscalls information.  */
/* Structure that represents syscalls information.  */
struct syscalls_info
struct syscalls_info
{
{
  /* The syscalls.  */
  /* The syscalls.  */
 
 
  VEC(syscall_desc_p) *syscalls;
  VEC(syscall_desc_p) *syscalls;
};
};
 
 
/* Callback data for syscall information parsing.  */
/* Callback data for syscall information parsing.  */
struct syscall_parsing_data
struct syscall_parsing_data
{
{
  /* The syscalls_info we are building.  */
  /* The syscalls_info we are building.  */
 
 
  struct syscalls_info *sysinfo;
  struct syscalls_info *sysinfo;
};
};
 
 
/* Structure used to store information about the available syscalls in
/* Structure used to store information about the available syscalls in
   the system.  */
   the system.  */
static const struct syscalls_info *sysinfo = NULL;
static const struct syscalls_info *sysinfo = NULL;
 
 
/* A flag to tell if we already initialized the structure above.  */
/* A flag to tell if we already initialized the structure above.  */
static int have_initialized_sysinfo = 0;
static int have_initialized_sysinfo = 0;
 
 
/* The filename of the syscall's XML.  */
/* The filename of the syscall's XML.  */
static const char *xml_syscall_file = NULL;
static const char *xml_syscall_file = NULL;
 
 
static struct syscalls_info *
static struct syscalls_info *
allocate_syscalls_info (void)
allocate_syscalls_info (void)
{
{
  return XZALLOC (struct syscalls_info);
  return XZALLOC (struct syscalls_info);
}
}
 
 
static void
static void
sysinfo_free_syscalls_desc (struct syscall_desc *sd)
sysinfo_free_syscalls_desc (struct syscall_desc *sd)
{
{
  xfree (sd->name);
  xfree (sd->name);
}
}
 
 
static void
static void
free_syscalls_info (void *arg)
free_syscalls_info (void *arg)
{
{
  struct syscalls_info *sysinfo = arg;
  struct syscalls_info *sysinfo = arg;
  struct syscall_desc *sysdesc;
  struct syscall_desc *sysdesc;
  int i;
  int i;
 
 
  for (i = 0;
  for (i = 0;
       VEC_iterate (syscall_desc_p, sysinfo->syscalls, i, sysdesc);
       VEC_iterate (syscall_desc_p, sysinfo->syscalls, i, sysdesc);
       i++)
       i++)
    sysinfo_free_syscalls_desc (sysdesc);
    sysinfo_free_syscalls_desc (sysdesc);
  VEC_free (syscall_desc_p, sysinfo->syscalls);
  VEC_free (syscall_desc_p, sysinfo->syscalls);
 
 
  xfree (sysinfo);
  xfree (sysinfo);
}
}
 
 
struct cleanup *
struct cleanup *
make_cleanup_free_syscalls_info (struct syscalls_info *sysinfo)
make_cleanup_free_syscalls_info (struct syscalls_info *sysinfo)
{
{
  return make_cleanup (free_syscalls_info, sysinfo);
  return make_cleanup (free_syscalls_info, sysinfo);
}
}
 
 
static void
static void
syscall_create_syscall_desc (struct syscalls_info *sysinfo,
syscall_create_syscall_desc (struct syscalls_info *sysinfo,
                             const char *name, int number)
                             const char *name, int number)
{
{
  struct syscall_desc *sysdesc = XZALLOC (struct syscall_desc);
  struct syscall_desc *sysdesc = XZALLOC (struct syscall_desc);
 
 
  sysdesc->name = xstrdup (name);
  sysdesc->name = xstrdup (name);
  sysdesc->number = number;
  sysdesc->number = number;
 
 
  VEC_safe_push (syscall_desc_p, sysinfo->syscalls, sysdesc);
  VEC_safe_push (syscall_desc_p, sysinfo->syscalls, sysdesc);
}
}
 
 
/* Handle the start of a <syscalls_info> element.  */
/* Handle the start of a <syscalls_info> element.  */
static void
static void
syscall_start_syscalls_info (struct gdb_xml_parser *parser,
syscall_start_syscalls_info (struct gdb_xml_parser *parser,
                             const struct gdb_xml_element *element,
                             const struct gdb_xml_element *element,
                             void *user_data,
                             void *user_data,
                             VEC(gdb_xml_value_s) *attributes)
                             VEC(gdb_xml_value_s) *attributes)
{
{
  struct syscall_parsing_data *data = user_data;
  struct syscall_parsing_data *data = user_data;
  struct syscalls_info *sysinfo = data->sysinfo;
  struct syscalls_info *sysinfo = data->sysinfo;
}
}
 
 
/* Handle the start of a <syscall> element.  */
/* Handle the start of a <syscall> element.  */
static void
static void
syscall_start_syscall (struct gdb_xml_parser *parser,
syscall_start_syscall (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)
{
{
  struct syscall_parsing_data *data = user_data;
  struct syscall_parsing_data *data = user_data;
  struct gdb_xml_value *attrs = VEC_address (gdb_xml_value_s, attributes);
  struct gdb_xml_value *attrs = VEC_address (gdb_xml_value_s, attributes);
  int len, i;
  int len, i;
  /* syscall info.  */
  /* syscall info.  */
  char *name = NULL;
  char *name = NULL;
  int number = 0;
  int number = 0;
 
 
  len = VEC_length (gdb_xml_value_s, attributes);
  len = VEC_length (gdb_xml_value_s, attributes);
 
 
  for (i = 0; i < len; i++)
  for (i = 0; i < len; i++)
    {
    {
      if (strcmp (attrs[i].name, "name") == 0)
      if (strcmp (attrs[i].name, "name") == 0)
        name = attrs[i].value;
        name = attrs[i].value;
      else if (strcmp (attrs[i].name, "number") == 0)
      else if (strcmp (attrs[i].name, "number") == 0)
        number = * (ULONGEST *) attrs[i].value;
        number = * (ULONGEST *) attrs[i].value;
      else
      else
        internal_error (__FILE__, __LINE__,
        internal_error (__FILE__, __LINE__,
                        _("Unknown attribute name '%s'."), attrs[i].name);
                        _("Unknown attribute name '%s'."), attrs[i].name);
    }
    }
 
 
  syscall_create_syscall_desc (data->sysinfo, name, number);
  syscall_create_syscall_desc (data->sysinfo, name, number);
}
}
 
 
 
 
/* The elements and attributes of an XML syscall document.  */
/* The elements and attributes of an XML syscall document.  */
static const struct gdb_xml_attribute syscall_attr[] = {
static const struct gdb_xml_attribute syscall_attr[] = {
  { "number", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
  { "number", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
  { "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 }
};
};
 
 
static const struct gdb_xml_element syscalls_info_children[] = {
static const struct gdb_xml_element syscalls_info_children[] = {
  { "syscall", syscall_attr, NULL,
  { "syscall", syscall_attr, NULL,
    GDB_XML_EF_OPTIONAL | GDB_XML_EF_REPEATABLE,
    GDB_XML_EF_OPTIONAL | GDB_XML_EF_REPEATABLE,
    syscall_start_syscall, NULL },
    syscall_start_syscall, NULL },
  { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
  { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
};
};
 
 
static const struct gdb_xml_element syselements[] = {
static const struct gdb_xml_element syselements[] = {
  { "syscalls_info", NULL, syscalls_info_children,
  { "syscalls_info", NULL, syscalls_info_children,
    GDB_XML_EF_NONE, syscall_start_syscalls_info, NULL },
    GDB_XML_EF_NONE, syscall_start_syscalls_info, NULL },
  { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
  { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
};
};
 
 
static struct syscalls_info *
static struct syscalls_info *
syscall_parse_xml (const char *document, xml_fetch_another fetcher,
syscall_parse_xml (const char *document, xml_fetch_another fetcher,
                   void *fetcher_baton)
                   void *fetcher_baton)
{
{
  struct cleanup *result_cleanup;
  struct cleanup *result_cleanup;
  struct gdb_xml_parser *parser;
  struct gdb_xml_parser *parser;
  struct syscall_parsing_data data;
  struct syscall_parsing_data data;
  char *expanded_text;
  char *expanded_text;
  int i;
  int i;
 
 
  parser = gdb_xml_create_parser_and_cleanup (_("syscalls info"),
  parser = gdb_xml_create_parser_and_cleanup (_("syscalls info"),
                                              syselements, &data);
                                              syselements, &data);
 
 
  memset (&data, 0, sizeof (struct syscall_parsing_data));
  memset (&data, 0, sizeof (struct syscall_parsing_data));
  data.sysinfo = allocate_syscalls_info ();
  data.sysinfo = allocate_syscalls_info ();
  result_cleanup = make_cleanup_free_syscalls_info (data.sysinfo);
  result_cleanup = make_cleanup_free_syscalls_info (data.sysinfo);
 
 
  if (gdb_xml_parse (parser, document) == 0)
  if (gdb_xml_parse (parser, document) == 0)
    {
    {
      /* Parsed successfully.  */
      /* Parsed successfully.  */
      discard_cleanups (result_cleanup);
      discard_cleanups (result_cleanup);
      return data.sysinfo;
      return data.sysinfo;
    }
    }
  else
  else
    {
    {
      warning (_("Could not load XML syscalls info; ignoring"));
      warning (_("Could not load XML syscalls info; ignoring"));
      do_cleanups (result_cleanup);
      do_cleanups (result_cleanup);
      return NULL;
      return NULL;
    }
    }
}
}
 
 
/* Function responsible for initializing the information
/* Function responsible for initializing the information
   about the syscalls.  It reads the XML file and fills the
   about the syscalls.  It reads the XML file and fills the
   struct syscalls_info with the values.
   struct syscalls_info with the values.
 
 
   Returns the struct syscalls_info if the file is valid, NULL otherwise.  */
   Returns the struct syscalls_info if the file is valid, NULL otherwise.  */
static const struct syscalls_info *
static const struct syscalls_info *
xml_init_syscalls_info (const char *filename)
xml_init_syscalls_info (const char *filename)
{
{
  char *full_file;
  char *full_file;
  char *dirname;
  char *dirname;
  struct syscalls_info *sysinfo;
  struct syscalls_info *sysinfo;
  struct cleanup *back_to;
  struct cleanup *back_to;
 
 
  full_file = xml_fetch_content_from_file (filename, gdb_datadir);
  full_file = xml_fetch_content_from_file (filename, gdb_datadir);
  if (full_file == NULL)
  if (full_file == NULL)
    return NULL;
    return NULL;
 
 
  back_to = make_cleanup (xfree, full_file);
  back_to = make_cleanup (xfree, full_file);
 
 
  dirname = ldirname (filename);
  dirname = ldirname (filename);
  if (dirname != NULL)
  if (dirname != NULL)
    make_cleanup (xfree, dirname);
    make_cleanup (xfree, dirname);
 
 
  sysinfo = syscall_parse_xml (full_file, xml_fetch_content_from_file, dirname);
  sysinfo = syscall_parse_xml (full_file, xml_fetch_content_from_file, dirname);
  do_cleanups (back_to);
  do_cleanups (back_to);
 
 
  return sysinfo;
  return sysinfo;
}
}
 
 
/* Initializes the syscalls_info structure according to the
/* Initializes the syscalls_info structure according to the
   architecture.  */
   architecture.  */
static void
static void
init_sysinfo (void)
init_sysinfo (void)
{
{
  /* Did we already try to initialize the structure?  */
  /* Did we already try to initialize the structure?  */
  if (have_initialized_sysinfo)
  if (have_initialized_sysinfo)
    return;
    return;
 
 
  sysinfo = xml_init_syscalls_info (xml_syscall_file);
  sysinfo = xml_init_syscalls_info (xml_syscall_file);
 
 
  have_initialized_sysinfo = 1;
  have_initialized_sysinfo = 1;
 
 
  if (sysinfo == NULL)
  if (sysinfo == NULL)
    {
    {
      if (xml_syscall_file)
      if (xml_syscall_file)
        warning (_("\
        warning (_("\
Could not load the syscall XML file `%s'."), xml_syscall_file);
Could not load the syscall XML file `%s'."), xml_syscall_file);
      else
      else
        warning (_("\
        warning (_("\
There is no XML file to open."));
There is no XML file to open."));
 
 
      warning (_("\
      warning (_("\
GDB will not be able to display syscall names nor to verify if\n\
GDB will not be able to display syscall names nor to verify if\n\
any provided syscall numbers are valid."));
any provided syscall numbers are valid."));
    }
    }
}
}
 
 
static int
static int
xml_get_syscall_number (const struct syscalls_info *sysinfo,
xml_get_syscall_number (const struct syscalls_info *sysinfo,
                        const char *syscall_name)
                        const char *syscall_name)
{
{
  struct syscall_desc *sysdesc;
  struct syscall_desc *sysdesc;
  int i;
  int i;
 
 
  if (sysinfo == NULL
  if (sysinfo == NULL
      || syscall_name == NULL)
      || syscall_name == NULL)
    return UNKNOWN_SYSCALL;
    return UNKNOWN_SYSCALL;
 
 
  for (i = 0;
  for (i = 0;
       VEC_iterate(syscall_desc_p, sysinfo->syscalls, i, sysdesc);
       VEC_iterate(syscall_desc_p, sysinfo->syscalls, i, sysdesc);
       i++)
       i++)
    if (strcmp (sysdesc->name, syscall_name) == 0)
    if (strcmp (sysdesc->name, syscall_name) == 0)
      return sysdesc->number;
      return sysdesc->number;
 
 
  return UNKNOWN_SYSCALL;
  return UNKNOWN_SYSCALL;
}
}
 
 
static const char *
static const char *
xml_get_syscall_name (const struct syscalls_info *sysinfo,
xml_get_syscall_name (const struct syscalls_info *sysinfo,
                      int syscall_number)
                      int syscall_number)
{
{
  struct syscall_desc *sysdesc;
  struct syscall_desc *sysdesc;
  int i;
  int i;
 
 
  if (sysinfo == NULL
  if (sysinfo == NULL
      || syscall_number < 0)
      || syscall_number < 0)
    return NULL;
    return NULL;
 
 
  for (i = 0;
  for (i = 0;
       VEC_iterate(syscall_desc_p, sysinfo->syscalls, i, sysdesc);
       VEC_iterate(syscall_desc_p, sysinfo->syscalls, i, sysdesc);
       i++)
       i++)
    if (sysdesc->number == syscall_number)
    if (sysdesc->number == syscall_number)
      return sysdesc->name;
      return sysdesc->name;
 
 
  return NULL;
  return NULL;
}
}
 
 
static const char **
static const char **
xml_list_of_syscalls (const struct syscalls_info *sysinfo)
xml_list_of_syscalls (const struct syscalls_info *sysinfo)
{
{
  struct syscall_desc *sysdesc;
  struct syscall_desc *sysdesc;
  const char **names = NULL;
  const char **names = NULL;
  int nsyscalls;
  int nsyscalls;
  int i;
  int i;
 
 
  if (sysinfo == NULL)
  if (sysinfo == NULL)
    return NULL;
    return NULL;
 
 
  nsyscalls = VEC_length (syscall_desc_p, sysinfo->syscalls);
  nsyscalls = VEC_length (syscall_desc_p, sysinfo->syscalls);
  names = xmalloc ((nsyscalls + 1) * sizeof (char *));
  names = xmalloc ((nsyscalls + 1) * sizeof (char *));
 
 
  for (i = 0;
  for (i = 0;
       VEC_iterate (syscall_desc_p, sysinfo->syscalls, i, sysdesc);
       VEC_iterate (syscall_desc_p, sysinfo->syscalls, i, sysdesc);
       i++)
       i++)
    names[i] = sysdesc->name;
    names[i] = sysdesc->name;
 
 
  names[i] = NULL;
  names[i] = NULL;
 
 
  return names;
  return names;
}
}
 
 
void
void
set_xml_syscall_file_name (const char *name)
set_xml_syscall_file_name (const char *name)
{
{
  xml_syscall_file = name;
  xml_syscall_file = name;
}
}
 
 
void
void
get_syscall_by_number (int syscall_number,
get_syscall_by_number (int syscall_number,
                       struct syscall *s)
                       struct syscall *s)
{
{
  init_sysinfo ();
  init_sysinfo ();
 
 
  s->number = syscall_number;
  s->number = syscall_number;
  s->name = xml_get_syscall_name (sysinfo, syscall_number);
  s->name = xml_get_syscall_name (sysinfo, syscall_number);
}
}
 
 
void
void
get_syscall_by_name (const char *syscall_name,
get_syscall_by_name (const char *syscall_name,
                     struct syscall *s)
                     struct syscall *s)
{
{
  init_sysinfo ();
  init_sysinfo ();
 
 
  s->number = xml_get_syscall_number (sysinfo, syscall_name);
  s->number = xml_get_syscall_number (sysinfo, syscall_name);
  s->name = syscall_name;
  s->name = syscall_name;
}
}
 
 
const char **
const char **
get_syscall_names (void)
get_syscall_names (void)
{
{
  init_sysinfo ();
  init_sysinfo ();
 
 
  return xml_list_of_syscalls (sysinfo);
  return xml_list_of_syscalls (sysinfo);
}
}
 
 
#endif /* ! HAVE_LIBEXPAT */
#endif /* ! HAVE_LIBEXPAT */
 
 

powered by: WebSVN 2.1.0

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