Home | History | Annotate | Line # | Download | only in gdb
      1   1.1  christos /* Functions that provide the mechanism to parse a syscall XML file
      2   1.1  christos    and get its values.
      3   1.1  christos 
      4  1.11  christos    Copyright (C) 2009-2024 Free Software Foundation, Inc.
      5   1.1  christos 
      6   1.1  christos    This file is part of GDB.
      7   1.1  christos 
      8   1.1  christos    This program is free software; you can redistribute it and/or modify
      9   1.1  christos    it under the terms of the GNU General Public License as published by
     10   1.1  christos    the Free Software Foundation; either version 3 of the License, or
     11   1.1  christos    (at your option) any later version.
     12   1.1  christos 
     13   1.1  christos    This program is distributed in the hope that it will be useful,
     14   1.1  christos    but WITHOUT ANY WARRANTY; without even the implied warranty of
     15   1.1  christos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     16   1.1  christos    GNU General Public License for more details.
     17   1.1  christos 
     18   1.1  christos    You should have received a copy of the GNU General Public License
     19   1.1  christos    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
     20   1.1  christos 
     21   1.1  christos #include "gdbtypes.h"
     22   1.1  christos #include "xml-support.h"
     23   1.1  christos #include "xml-syscall.h"
     24   1.3  christos #include "gdbarch.h"
     25   1.1  christos 
     26   1.1  christos /* For the struct syscall definition.  */
     27   1.1  christos #include "target.h"
     28   1.1  christos 
     29   1.1  christos #include "filenames.h"
     30   1.1  christos 
     31   1.1  christos #ifndef HAVE_LIBEXPAT
     32   1.1  christos 
     33   1.1  christos /* Dummy functions to indicate that there's no support for fetching
     34   1.1  christos    syscalls information.  */
     35   1.1  christos 
     36   1.1  christos static void
     37   1.1  christos syscall_warn_user (void)
     38   1.1  christos {
     39   1.1  christos   static int have_warned = 0;
     40   1.1  christos   if (!have_warned)
     41   1.1  christos     {
     42   1.1  christos       have_warned = 1;
     43   1.1  christos       warning (_("Can not parse XML syscalls information; XML support was "
     44   1.1  christos 		 "disabled at compile time."));
     45   1.1  christos     }
     46   1.1  christos }
     47   1.1  christos 
     48   1.1  christos void
     49   1.3  christos set_xml_syscall_file_name (struct gdbarch *gdbarch, const char *name)
     50   1.1  christos {
     51   1.1  christos   return;
     52   1.1  christos }
     53   1.1  christos 
     54   1.1  christos void
     55   1.3  christos get_syscall_by_number (struct gdbarch *gdbarch,
     56   1.3  christos 		       int syscall_number, struct syscall *s)
     57   1.1  christos {
     58   1.1  christos   syscall_warn_user ();
     59   1.1  christos   s->number = syscall_number;
     60   1.1  christos   s->name = NULL;
     61   1.1  christos }
     62   1.1  christos 
     63   1.8  christos bool
     64   1.8  christos get_syscalls_by_name (struct gdbarch *gdbarch, const char *syscall_name,
     65   1.8  christos 		      std::vector<int> *syscall_numbers)
     66   1.1  christos {
     67   1.1  christos   syscall_warn_user ();
     68   1.8  christos   return false;
     69   1.1  christos }
     70   1.1  christos 
     71   1.1  christos const char **
     72   1.3  christos get_syscall_names (struct gdbarch *gdbarch)
     73   1.1  christos {
     74   1.1  christos   syscall_warn_user ();
     75   1.1  christos   return NULL;
     76   1.1  christos }
     77   1.1  christos 
     78   1.8  christos bool
     79   1.8  christos get_syscalls_by_group (struct gdbarch *gdbarch, const char *group,
     80   1.8  christos 		       std::vector<int> *syscall_numbers)
     81   1.6  christos {
     82   1.6  christos   syscall_warn_user ();
     83   1.8  christos   return false;
     84   1.6  christos }
     85   1.6  christos 
     86   1.6  christos const char **
     87   1.6  christos get_syscall_group_names (struct gdbarch *gdbarch)
     88   1.6  christos {
     89   1.6  christos   syscall_warn_user ();
     90   1.6  christos   return NULL;
     91   1.6  christos }
     92   1.6  christos 
     93   1.1  christos #else /* ! HAVE_LIBEXPAT */
     94   1.1  christos 
     95   1.1  christos /* Structure which describes a syscall.  */
     96   1.8  christos struct syscall_desc
     97   1.1  christos {
     98   1.8  christos   syscall_desc (int number_, std::string name_, std::string alias_)
     99   1.8  christos   : number (number_), name (name_), alias (alias_)
    100   1.8  christos   {}
    101   1.8  christos 
    102   1.1  christos   /* The syscall number.  */
    103   1.1  christos 
    104   1.1  christos   int number;
    105   1.1  christos 
    106   1.1  christos   /* The syscall name.  */
    107   1.1  christos 
    108   1.8  christos   std::string name;
    109   1.8  christos 
    110   1.8  christos   /* An optional alias.  */
    111   1.8  christos 
    112   1.8  christos   std::string alias;
    113   1.8  christos };
    114   1.8  christos 
    115   1.8  christos typedef std::unique_ptr<syscall_desc> syscall_desc_up;
    116   1.1  christos 
    117   1.6  christos /* Structure of a syscall group.  */
    118   1.8  christos struct syscall_group_desc
    119   1.6  christos {
    120   1.8  christos   syscall_group_desc (const std::string &name_)
    121   1.8  christos   : name (name_)
    122   1.8  christos   {}
    123   1.8  christos 
    124   1.6  christos   /* The group name.  */
    125   1.6  christos 
    126   1.8  christos   std::string name;
    127   1.6  christos 
    128   1.8  christos   /* The syscalls that are part of the group.  This is a non-owning
    129   1.8  christos      reference.  */
    130   1.8  christos 
    131   1.8  christos   std::vector<syscall_desc *> syscalls;
    132   1.8  christos };
    133   1.6  christos 
    134   1.8  christos typedef std::unique_ptr<syscall_group_desc> syscall_group_desc_up;
    135   1.6  christos 
    136   1.1  christos /* Structure that represents syscalls information.  */
    137   1.1  christos struct syscalls_info
    138   1.1  christos {
    139   1.1  christos   /* The syscalls.  */
    140   1.1  christos 
    141   1.8  christos   std::vector<syscall_desc_up> syscalls;
    142   1.3  christos 
    143   1.6  christos   /* The syscall groups.  */
    144   1.6  christos 
    145   1.8  christos   std::vector<syscall_group_desc_up> groups;
    146   1.6  christos 
    147   1.3  christos   /* Variable that will hold the last known data-directory.  This is
    148   1.3  christos      useful to know whether we should re-read the XML info for the
    149   1.3  christos      target.  */
    150   1.3  christos 
    151   1.8  christos   std::string my_gdb_datadir;
    152   1.1  christos };
    153   1.1  christos 
    154   1.8  christos typedef std::unique_ptr<syscalls_info> syscalls_info_up;
    155   1.8  christos 
    156   1.1  christos /* Callback data for syscall information parsing.  */
    157   1.1  christos struct syscall_parsing_data
    158   1.1  christos {
    159   1.1  christos   /* The syscalls_info we are building.  */
    160   1.1  christos 
    161   1.3  christos   struct syscalls_info *syscalls_info;
    162   1.1  christos };
    163   1.1  christos 
    164   1.6  christos /* Create a new syscall group.  Return pointer to the
    165   1.6  christos    syscall_group_desc structure that represents the new group.  */
    166   1.6  christos 
    167   1.6  christos static struct syscall_group_desc *
    168   1.6  christos syscall_group_create_syscall_group_desc (struct syscalls_info *syscalls_info,
    169   1.6  christos 					 const char *group)
    170   1.6  christos {
    171   1.8  christos   syscall_group_desc *groupdesc = new syscall_group_desc (group);
    172   1.6  christos 
    173   1.8  christos   syscalls_info->groups.emplace_back (groupdesc);
    174   1.6  christos 
    175   1.6  christos   return groupdesc;
    176   1.6  christos }
    177   1.6  christos 
    178   1.6  christos /* Add a syscall to the group.  If group doesn't exist, create it.  */
    179   1.6  christos 
    180   1.6  christos static void
    181   1.6  christos syscall_group_add_syscall (struct syscalls_info *syscalls_info,
    182   1.6  christos 			   struct syscall_desc *syscall,
    183   1.6  christos 			   const char *group)
    184   1.6  christos {
    185   1.8  christos   /* Search for an existing group.  */
    186   1.8  christos   std::vector<syscall_group_desc_up>::iterator it
    187   1.8  christos     = syscalls_info->groups.begin ();
    188   1.6  christos 
    189   1.8  christos   for (; it != syscalls_info->groups.end (); it++)
    190   1.6  christos     {
    191   1.8  christos       if ((*it)->name == group)
    192   1.6  christos 	break;
    193   1.6  christos     }
    194   1.6  christos 
    195   1.8  christos   syscall_group_desc *groupdesc;
    196   1.8  christos 
    197   1.8  christos   if (it != syscalls_info->groups.end ())
    198   1.8  christos     groupdesc = it->get ();
    199   1.8  christos   else
    200   1.6  christos     {
    201   1.6  christos       /* No group was found with this name.  We must create a new
    202   1.6  christos 	 one.  */
    203   1.6  christos       groupdesc = syscall_group_create_syscall_group_desc (syscalls_info,
    204   1.6  christos 							   group);
    205   1.6  christos     }
    206   1.6  christos 
    207   1.8  christos   groupdesc->syscalls.push_back (syscall);
    208   1.6  christos }
    209   1.6  christos 
    210   1.1  christos static void
    211   1.3  christos syscall_create_syscall_desc (struct syscalls_info *syscalls_info,
    212   1.8  christos 			     const char *name, int number, const char *alias,
    213   1.6  christos 			     char *groups)
    214   1.1  christos {
    215   1.8  christos   syscall_desc *sysdesc = new syscall_desc (number, name,
    216   1.8  christos 					    alias != NULL ? alias : "");
    217   1.1  christos 
    218   1.8  christos   syscalls_info->syscalls.emplace_back (sysdesc);
    219   1.6  christos 
    220   1.6  christos   /*  Add syscall to its groups.  */
    221   1.6  christos   if (groups != NULL)
    222   1.6  christos     {
    223   1.9  christos       char *saveptr;
    224   1.9  christos       for (char *group = strtok_r (groups, ",", &saveptr);
    225   1.6  christos 	   group != NULL;
    226   1.9  christos 	   group = strtok_r (NULL, ",", &saveptr))
    227   1.6  christos 	syscall_group_add_syscall (syscalls_info, sysdesc, group);
    228   1.6  christos     }
    229   1.1  christos }
    230   1.1  christos 
    231   1.1  christos /* Handle the start of a <syscall> element.  */
    232   1.1  christos static void
    233   1.1  christos syscall_start_syscall (struct gdb_xml_parser *parser,
    234  1.10  christos 		       const struct gdb_xml_element *element,
    235  1.10  christos 		       void *user_data,
    236   1.8  christos 		       std::vector<gdb_xml_value> &attributes)
    237   1.1  christos {
    238   1.6  christos   struct syscall_parsing_data *data = (struct syscall_parsing_data *) user_data;
    239   1.1  christos   /* syscall info.  */
    240   1.1  christos   char *name = NULL;
    241   1.1  christos   int number = 0;
    242   1.8  christos   char *alias = NULL;
    243   1.6  christos   char *groups = NULL;
    244   1.1  christos 
    245   1.8  christos   for (const gdb_xml_value &attr : attributes)
    246   1.1  christos     {
    247   1.8  christos       if (strcmp (attr.name, "name") == 0)
    248  1.10  christos 	name = (char *) attr.value.get ();
    249   1.8  christos       else if (strcmp (attr.name, "number") == 0)
    250  1.10  christos 	number = * (ULONGEST *) attr.value.get ();
    251   1.8  christos       else if (strcmp (attr.name, "alias") == 0)
    252  1.10  christos 	alias = (char *) attr.value.get ();
    253   1.8  christos       else if (strcmp (attr.name, "groups") == 0)
    254  1.10  christos 	groups = (char *) attr.value.get ();
    255   1.1  christos       else
    256  1.10  christos 	internal_error (_("Unknown attribute name '%s'."), attr.name);
    257   1.1  christos     }
    258   1.1  christos 
    259   1.1  christos   gdb_assert (name);
    260   1.8  christos   syscall_create_syscall_desc (data->syscalls_info, name, number, alias,
    261   1.8  christos 			       groups);
    262   1.1  christos }
    263   1.1  christos 
    264   1.1  christos 
    265   1.1  christos /* The elements and attributes of an XML syscall document.  */
    266   1.1  christos static const struct gdb_xml_attribute syscall_attr[] = {
    267   1.1  christos   { "number", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
    268   1.1  christos   { "name", GDB_XML_AF_NONE, NULL, NULL },
    269   1.8  christos   { "alias", GDB_XML_AF_OPTIONAL, NULL, NULL },
    270   1.6  christos   { "groups", GDB_XML_AF_OPTIONAL, NULL, NULL },
    271   1.1  christos   { NULL, GDB_XML_AF_NONE, NULL, NULL }
    272   1.1  christos };
    273   1.1  christos 
    274   1.1  christos static const struct gdb_xml_element syscalls_info_children[] = {
    275   1.1  christos   { "syscall", syscall_attr, NULL,
    276   1.1  christos     GDB_XML_EF_OPTIONAL | GDB_XML_EF_REPEATABLE,
    277   1.1  christos     syscall_start_syscall, NULL },
    278   1.1  christos   { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
    279   1.1  christos };
    280   1.1  christos 
    281   1.1  christos static const struct gdb_xml_element syselements[] = {
    282   1.1  christos   { "syscalls_info", NULL, syscalls_info_children,
    283   1.1  christos     GDB_XML_EF_NONE, NULL, NULL },
    284   1.1  christos   { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
    285   1.1  christos };
    286   1.1  christos 
    287   1.1  christos static struct syscalls_info *
    288  1.10  christos syscall_parse_xml (const char *document, xml_fetch_another fetcher)
    289   1.1  christos {
    290   1.1  christos   struct syscall_parsing_data data;
    291   1.8  christos   syscalls_info_up sysinfo (new syscalls_info ());
    292   1.1  christos 
    293   1.8  christos   data.syscalls_info = sysinfo.get ();
    294   1.1  christos 
    295   1.1  christos   if (gdb_xml_parse_quick (_("syscalls info"), NULL,
    296   1.1  christos 			   syselements, document, &data) == 0)
    297   1.1  christos     {
    298   1.1  christos       /* Parsed successfully.  */
    299   1.8  christos       return sysinfo.release ();
    300   1.1  christos     }
    301   1.1  christos   else
    302   1.1  christos     {
    303   1.1  christos       warning (_("Could not load XML syscalls info; ignoring"));
    304   1.1  christos       return NULL;
    305   1.1  christos     }
    306   1.1  christos }
    307   1.1  christos 
    308   1.1  christos /* Function responsible for initializing the information
    309   1.1  christos    about the syscalls.  It reads the XML file and fills the
    310   1.1  christos    struct syscalls_info with the values.
    311   1.1  christos 
    312   1.1  christos    Returns the struct syscalls_info if the file is valid, NULL otherwise.  */
    313   1.3  christos static struct syscalls_info *
    314   1.1  christos xml_init_syscalls_info (const char *filename)
    315   1.1  christos {
    316  1.11  christos   std::optional<gdb::char_vector> full_file
    317   1.9  christos     = xml_fetch_content_from_file (filename,
    318   1.9  christos 				   const_cast<char *>(gdb_datadir.c_str ()));
    319   1.8  christos   if (!full_file)
    320   1.1  christos     return NULL;
    321   1.1  christos 
    322  1.10  christos   const std::string dirname = ldirname (filename);
    323  1.10  christos   auto fetch_another = [&dirname] (const char *name)
    324  1.10  christos     {
    325  1.10  christos       return xml_fetch_content_from_file (name, dirname.c_str ());
    326  1.10  christos     };
    327  1.10  christos 
    328  1.10  christos   return syscall_parse_xml (full_file->data (), fetch_another);
    329   1.1  christos }
    330   1.1  christos 
    331   1.1  christos /* Initializes the syscalls_info structure according to the
    332   1.1  christos    architecture.  */
    333   1.1  christos static void
    334   1.3  christos init_syscalls_info (struct gdbarch *gdbarch)
    335   1.1  christos {
    336   1.3  christos   struct syscalls_info *syscalls_info = gdbarch_syscalls_info (gdbarch);
    337   1.3  christos   const char *xml_syscall_file = gdbarch_xml_syscall_file (gdbarch);
    338   1.3  christos 
    339   1.1  christos   /* Should we re-read the XML info for this target?  */
    340   1.8  christos   if (syscalls_info != NULL && !syscalls_info->my_gdb_datadir.empty ()
    341   1.8  christos       && filename_cmp (syscalls_info->my_gdb_datadir.c_str (),
    342   1.9  christos 		       gdb_datadir.c_str ()) != 0)
    343   1.1  christos     {
    344   1.1  christos       /* The data-directory changed from the last time we used it.
    345   1.1  christos 	 It means that we have to re-read the XML info.  */
    346   1.8  christos       delete syscalls_info;
    347   1.3  christos       syscalls_info = NULL;
    348   1.3  christos       set_gdbarch_syscalls_info (gdbarch, NULL);
    349   1.1  christos     }
    350   1.1  christos 
    351   1.3  christos   /* Did we succeed at initializing this?  */
    352   1.3  christos   if (syscalls_info != NULL)
    353   1.1  christos     return;
    354   1.1  christos 
    355   1.3  christos   syscalls_info = xml_init_syscalls_info (xml_syscall_file);
    356   1.1  christos 
    357   1.3  christos   /* If there was some error reading the XML file, we initialize
    358   1.3  christos      gdbarch->syscalls_info anyway, in order to store information
    359   1.3  christos      about our attempt.  */
    360   1.3  christos   if (syscalls_info == NULL)
    361   1.8  christos     syscalls_info = new struct syscalls_info ();
    362   1.1  christos 
    363   1.8  christos   if (syscalls_info->syscalls.empty ())
    364   1.1  christos     {
    365   1.3  christos       if (xml_syscall_file != NULL)
    366   1.1  christos 	warning (_("Could not load the syscall XML file `%s/%s'."),
    367   1.9  christos 		 gdb_datadir.c_str (), xml_syscall_file);
    368   1.1  christos       else
    369   1.1  christos 	warning (_("There is no XML file to open."));
    370   1.1  christos 
    371   1.1  christos       warning (_("GDB will not be able to display "
    372   1.1  christos 		 "syscall names nor to verify if\n"
    373   1.1  christos 		 "any provided syscall numbers are valid."));
    374   1.1  christos     }
    375   1.1  christos 
    376   1.1  christos   /* Saving the data-directory used to read this XML info.  */
    377   1.8  christos   syscalls_info->my_gdb_datadir.assign (gdb_datadir);
    378   1.3  christos 
    379   1.3  christos   set_gdbarch_syscalls_info (gdbarch, syscalls_info);
    380   1.1  christos }
    381   1.1  christos 
    382   1.6  christos /* Search for a syscall group by its name.  Return syscall_group_desc
    383   1.6  christos    structure for the group if found or NULL otherwise.  */
    384   1.6  christos 
    385   1.6  christos static struct syscall_group_desc *
    386   1.6  christos syscall_group_get_group_by_name (const struct syscalls_info *syscalls_info,
    387   1.6  christos 				 const char *group)
    388   1.6  christos {
    389   1.6  christos   if (syscalls_info == NULL)
    390   1.6  christos     return NULL;
    391   1.6  christos 
    392   1.6  christos   if (group == NULL)
    393   1.6  christos     return NULL;
    394   1.6  christos 
    395   1.8  christos   /* Search for existing group.  */
    396   1.8  christos   for (const syscall_group_desc_up &groupdesc : syscalls_info->groups)
    397   1.6  christos     {
    398   1.8  christos       if (groupdesc->name == group)
    399   1.8  christos 	return groupdesc.get ();
    400   1.6  christos     }
    401   1.6  christos 
    402   1.6  christos   return NULL;
    403   1.6  christos }
    404   1.6  christos 
    405   1.8  christos static bool
    406   1.8  christos xml_get_syscalls_by_name (struct gdbarch *gdbarch, const char *syscall_name,
    407   1.8  christos 			  std::vector<int> *syscall_numbers)
    408   1.1  christos {
    409   1.3  christos   struct syscalls_info *syscalls_info = gdbarch_syscalls_info (gdbarch);
    410   1.1  christos 
    411   1.8  christos   bool found = false;
    412   1.8  christos   if (syscalls_info != NULL && syscall_name != NULL && syscall_numbers != NULL)
    413   1.8  christos     for (const syscall_desc_up &sysdesc : syscalls_info->syscalls)
    414   1.8  christos       if (sysdesc->name == syscall_name || sysdesc->alias == syscall_name)
    415   1.8  christos 	{
    416   1.8  christos 	  syscall_numbers->push_back (sysdesc->number);
    417   1.8  christos 	  found = true;
    418   1.8  christos 	}
    419   1.1  christos 
    420   1.8  christos   return found;
    421   1.1  christos }
    422   1.1  christos 
    423   1.1  christos static const char *
    424   1.3  christos xml_get_syscall_name (struct gdbarch *gdbarch,
    425  1.10  christos 		      int syscall_number)
    426   1.1  christos {
    427   1.3  christos   struct syscalls_info *syscalls_info = gdbarch_syscalls_info (gdbarch);
    428   1.1  christos 
    429   1.3  christos   if (syscalls_info == NULL
    430   1.1  christos       || syscall_number < 0)
    431   1.1  christos     return NULL;
    432   1.1  christos 
    433   1.8  christos   for (const syscall_desc_up &sysdesc : syscalls_info->syscalls)
    434   1.1  christos     if (sysdesc->number == syscall_number)
    435   1.8  christos       return sysdesc->name.c_str ();
    436   1.1  christos 
    437   1.1  christos   return NULL;
    438   1.1  christos }
    439   1.1  christos 
    440   1.1  christos static const char **
    441   1.3  christos xml_list_of_syscalls (struct gdbarch *gdbarch)
    442   1.1  christos {
    443   1.3  christos   struct syscalls_info *syscalls_info = gdbarch_syscalls_info (gdbarch);
    444   1.1  christos 
    445   1.3  christos   if (syscalls_info == NULL)
    446   1.1  christos     return NULL;
    447   1.1  christos 
    448   1.8  christos   int nsyscalls = syscalls_info->syscalls.size ();
    449   1.8  christos   const char **names = XNEWVEC (const char *, nsyscalls + 1);
    450   1.1  christos 
    451   1.8  christos   int i;
    452   1.8  christos   for (i = 0; i < syscalls_info->syscalls.size (); i++)
    453   1.8  christos     names[i] = syscalls_info->syscalls[i]->name.c_str ();
    454   1.1  christos 
    455   1.1  christos   names[i] = NULL;
    456   1.1  christos 
    457   1.1  christos   return names;
    458   1.1  christos }
    459   1.1  christos 
    460   1.6  christos /* Iterate over the syscall_group_desc element to return a list of
    461   1.8  christos    syscalls that are part of the given group.  If the syscall group
    462   1.8  christos    doesn't exist, return false.  */
    463   1.6  christos 
    464   1.8  christos static bool
    465   1.8  christos xml_list_syscalls_by_group (struct gdbarch *gdbarch, const char *group,
    466   1.8  christos 			    std::vector<int> *syscalls)
    467   1.6  christos {
    468   1.6  christos   struct syscalls_info *syscalls_info = gdbarch_syscalls_info (gdbarch);
    469   1.6  christos   struct syscall_group_desc *groupdesc;
    470   1.6  christos 
    471   1.8  christos   if (syscalls_info == NULL || syscalls == NULL)
    472   1.8  christos     return false;
    473   1.6  christos 
    474   1.6  christos   groupdesc = syscall_group_get_group_by_name (syscalls_info, group);
    475   1.6  christos   if (groupdesc == NULL)
    476   1.8  christos     return false;
    477   1.6  christos 
    478   1.8  christos   for (const syscall_desc *sysdesc : groupdesc->syscalls)
    479   1.8  christos     syscalls->push_back (sysdesc->number);
    480   1.6  christos 
    481   1.8  christos   return true;
    482   1.6  christos }
    483   1.6  christos 
    484   1.6  christos /* Return a NULL terminated list of syscall groups or an empty list, if
    485   1.6  christos    no syscall group is available.  Return NULL, if there is no syscall
    486   1.6  christos    information available.  */
    487   1.6  christos 
    488   1.6  christos static const char **
    489   1.6  christos xml_list_of_groups (struct gdbarch *gdbarch)
    490   1.6  christos {
    491   1.6  christos   struct syscalls_info *syscalls_info = gdbarch_syscalls_info (gdbarch);
    492   1.6  christos   const char **names = NULL;
    493   1.8  christos   int ngroups;
    494   1.6  christos   int i;
    495   1.6  christos 
    496   1.6  christos   if (syscalls_info == NULL)
    497   1.6  christos     return NULL;
    498   1.6  christos 
    499   1.8  christos   ngroups = syscalls_info->groups.size ();
    500   1.6  christos   names = (const char**) xmalloc ((ngroups + 1) * sizeof (char *));
    501   1.6  christos 
    502   1.8  christos   for (i = 0; i < syscalls_info->groups.size (); i++)
    503   1.8  christos     names[i] = syscalls_info->groups[i]->name.c_str ();
    504   1.6  christos 
    505   1.6  christos   names[i] = NULL;
    506   1.6  christos 
    507   1.6  christos   return names;
    508   1.6  christos }
    509   1.6  christos 
    510   1.1  christos void
    511   1.3  christos set_xml_syscall_file_name (struct gdbarch *gdbarch, const char *name)
    512   1.1  christos {
    513   1.3  christos   set_gdbarch_xml_syscall_file (gdbarch, name);
    514   1.1  christos }
    515   1.1  christos 
    516   1.1  christos void
    517   1.3  christos get_syscall_by_number (struct gdbarch *gdbarch,
    518   1.3  christos 		       int syscall_number, struct syscall *s)
    519   1.1  christos {
    520   1.3  christos   init_syscalls_info (gdbarch);
    521   1.1  christos 
    522   1.1  christos   s->number = syscall_number;
    523   1.3  christos   s->name = xml_get_syscall_name (gdbarch, syscall_number);
    524   1.1  christos }
    525   1.1  christos 
    526   1.8  christos bool
    527   1.8  christos get_syscalls_by_name (struct gdbarch *gdbarch, const char *syscall_name,
    528   1.8  christos 		      std::vector<int> *syscall_numbers)
    529   1.1  christos {
    530   1.3  christos   init_syscalls_info (gdbarch);
    531   1.1  christos 
    532   1.8  christos   return xml_get_syscalls_by_name (gdbarch, syscall_name, syscall_numbers);
    533   1.1  christos }
    534   1.1  christos 
    535   1.1  christos const char **
    536   1.3  christos get_syscall_names (struct gdbarch *gdbarch)
    537   1.1  christos {
    538   1.3  christos   init_syscalls_info (gdbarch);
    539   1.1  christos 
    540   1.3  christos   return xml_list_of_syscalls (gdbarch);
    541   1.1  christos }
    542   1.1  christos 
    543   1.6  christos /* See comment in xml-syscall.h.  */
    544   1.6  christos 
    545   1.8  christos bool
    546   1.8  christos get_syscalls_by_group (struct gdbarch *gdbarch, const char *group,
    547   1.8  christos 		       std::vector<int> *syscall_numbers)
    548   1.6  christos {
    549   1.6  christos   init_syscalls_info (gdbarch);
    550   1.6  christos 
    551   1.8  christos   return xml_list_syscalls_by_group (gdbarch, group, syscall_numbers);
    552   1.6  christos }
    553   1.6  christos 
    554   1.6  christos /* See comment in xml-syscall.h.  */
    555   1.6  christos 
    556   1.6  christos const char **
    557   1.6  christos get_syscall_group_names (struct gdbarch *gdbarch)
    558   1.6  christos {
    559   1.6  christos   init_syscalls_info (gdbarch);
    560   1.6  christos 
    561   1.6  christos   return xml_list_of_groups (gdbarch);
    562   1.6  christos }
    563   1.6  christos 
    564   1.1  christos #endif /* ! HAVE_LIBEXPAT */
    565