/* Functions that provide the mechanism to parse a syscall XML file
and get its values.
- Copyright (C) 2009-2018 Free Software Foundation, Inc.
+ Copyright (C) 2009-2019 Free Software Foundation, Inc.
This file is part of GDB.
s->name = NULL;
}
-void
-get_syscall_by_name (struct gdbarch *gdbarch, const char *syscall_name,
- struct syscall *s)
+bool
+get_syscalls_by_name (struct gdbarch *gdbarch, const char *syscall_name,
+ std::vector<int> *syscall_numbers)
{
syscall_warn_user ();
- s->number = UNKNOWN_SYSCALL;
- s->name = syscall_name;
+ return false;
}
const char **
return NULL;
}
-struct syscall *
-get_syscalls_by_group (struct gdbarch *gdbarch, const char *group)
+bool
+get_syscalls_by_group (struct gdbarch *gdbarch, const char *group,
+ std::vector<int> *syscall_numbers)
{
syscall_warn_user ();
- return NULL;
+ return false;
}
const char **
/* Structure which describes a syscall. */
struct syscall_desc
{
- syscall_desc (int number_, std::string name_)
- : number (number_), name (name_)
+ syscall_desc (int number_, std::string name_, std::string alias_)
+ : number (number_), name (name_), alias (alias_)
{}
/* The syscall number. */
/* The syscall name. */
std::string name;
+
+ /* An optional alias. */
+
+ std::string alias;
};
typedef std::unique_ptr<syscall_desc> syscall_desc_up;
static void
syscall_create_syscall_desc (struct syscalls_info *syscalls_info,
- const char *name, int number,
+ const char *name, int number, const char *alias,
char *groups)
{
- syscall_desc *sysdesc = new syscall_desc (number, name);
+ syscall_desc *sysdesc = new syscall_desc (number, name,
+ alias != NULL ? alias : "");
syscalls_info->syscalls.emplace_back (sysdesc);
static void
syscall_start_syscall (struct gdb_xml_parser *parser,
const struct gdb_xml_element *element,
- void *user_data, VEC(gdb_xml_value_s) *attributes)
+ void *user_data,
+ std::vector<gdb_xml_value> &attributes)
{
struct syscall_parsing_data *data = (struct syscall_parsing_data *) user_data;
- struct gdb_xml_value *attrs = VEC_address (gdb_xml_value_s, attributes);
- int len, i;
/* syscall info. */
char *name = NULL;
int number = 0;
+ char *alias = NULL;
char *groups = NULL;
- len = VEC_length (gdb_xml_value_s, attributes);
-
- for (i = 0; i < len; i++)
+ for (const gdb_xml_value &attr : attributes)
{
- if (strcmp (attrs[i].name, "name") == 0)
- name = (char *) attrs[i].value;
- else if (strcmp (attrs[i].name, "number") == 0)
- number = * (ULONGEST *) attrs[i].value;
- else if (strcmp (attrs[i].name, "groups") == 0)
- groups = (char *) attrs[i].value;
+ if (strcmp (attr.name, "name") == 0)
+ name = (char *) attr.value.get ();
+ else if (strcmp (attr.name, "number") == 0)
+ number = * (ULONGEST *) attr.value.get ();
+ else if (strcmp (attr.name, "alias") == 0)
+ alias = (char *) attr.value.get ();
+ else if (strcmp (attr.name, "groups") == 0)
+ groups = (char *) attr.value.get ();
else
internal_error (__FILE__, __LINE__,
- _("Unknown attribute name '%s'."), attrs[i].name);
+ _("Unknown attribute name '%s'."), attr.name);
}
gdb_assert (name);
- syscall_create_syscall_desc (data->syscalls_info, name, number, groups);
+ syscall_create_syscall_desc (data->syscalls_info, name, number, alias,
+ groups);
}
static const struct gdb_xml_attribute syscall_attr[] = {
{ "number", GDB_XML_AF_NONE, gdb_xml_parse_attr_ulongest, NULL },
{ "name", GDB_XML_AF_NONE, NULL, NULL },
+ { "alias", GDB_XML_AF_OPTIONAL, NULL, NULL },
{ "groups", GDB_XML_AF_OPTIONAL, NULL, NULL },
{ NULL, GDB_XML_AF_NONE, NULL, NULL }
};
static struct syscalls_info *
xml_init_syscalls_info (const char *filename)
{
- gdb::unique_xmalloc_ptr<char> full_file
+ gdb::optional<gdb::char_vector> full_file
= xml_fetch_content_from_file (filename, gdb_datadir);
- if (full_file == NULL)
+ if (!full_file)
return NULL;
- return syscall_parse_xml (full_file.get (),
+ return syscall_parse_xml (full_file->data (),
xml_fetch_content_from_file,
(void *) ldirname (filename).c_str ());
}
return NULL;
}
-static int
-xml_get_syscall_number (struct gdbarch *gdbarch,
- const char *syscall_name)
+static bool
+xml_get_syscalls_by_name (struct gdbarch *gdbarch, const char *syscall_name,
+ std::vector<int> *syscall_numbers)
{
struct syscalls_info *syscalls_info = gdbarch_syscalls_info (gdbarch);
- if (syscalls_info == NULL
- || syscall_name == NULL)
- return UNKNOWN_SYSCALL;
-
- for (const syscall_desc_up &sysdesc : syscalls_info->syscalls)
- if (sysdesc->name == syscall_name)
- return sysdesc->number;
+ bool found = false;
+ if (syscalls_info != NULL && syscall_name != NULL && syscall_numbers != NULL)
+ for (const syscall_desc_up &sysdesc : syscalls_info->syscalls)
+ if (sysdesc->name == syscall_name || sysdesc->alias == syscall_name)
+ {
+ syscall_numbers->push_back (sysdesc->number);
+ found = true;
+ }
- return UNKNOWN_SYSCALL;
+ return found;
}
static const char *
}
/* Iterate over the syscall_group_desc element to return a list of
- syscalls that are part of the given group, terminated by an empty
- element. If the syscall group doesn't exist, return NULL. */
+ syscalls that are part of the given group. If the syscall group
+ doesn't exist, return false. */
-static struct syscall *
-xml_list_syscalls_by_group (struct gdbarch *gdbarch, const char *group)
+static bool
+xml_list_syscalls_by_group (struct gdbarch *gdbarch, const char *group,
+ std::vector<int> *syscalls)
{
struct syscalls_info *syscalls_info = gdbarch_syscalls_info (gdbarch);
struct syscall_group_desc *groupdesc;
- struct syscall *syscalls = NULL;
- int nsyscalls;
- int i;
- if (syscalls_info == NULL)
- return NULL;
+ if (syscalls_info == NULL || syscalls == NULL)
+ return false;
groupdesc = syscall_group_get_group_by_name (syscalls_info, group);
if (groupdesc == NULL)
- return NULL;
-
- nsyscalls = groupdesc->syscalls.size ();
- syscalls = (struct syscall*) xmalloc ((nsyscalls + 1)
- * sizeof (struct syscall));
+ return false;
- for (i = 0; i < groupdesc->syscalls.size (); i++)
- {
- syscalls[i].name = groupdesc->syscalls[i]->name.c_str ();
- syscalls[i].number = groupdesc->syscalls[i]->number;
- }
+ for (const syscall_desc *sysdesc : groupdesc->syscalls)
+ syscalls->push_back (sysdesc->number);
- /* Add final element marker. */
- syscalls[i].name = NULL;
- syscalls[i].number = 0;
-
- return syscalls;
+ return true;
}
/* Return a NULL terminated list of syscall groups or an empty list, if
s->name = xml_get_syscall_name (gdbarch, syscall_number);
}
-void
-get_syscall_by_name (struct gdbarch *gdbarch,
- const char *syscall_name, struct syscall *s)
+bool
+get_syscalls_by_name (struct gdbarch *gdbarch, const char *syscall_name,
+ std::vector<int> *syscall_numbers)
{
init_syscalls_info (gdbarch);
- s->number = xml_get_syscall_number (gdbarch, syscall_name);
- s->name = syscall_name;
+ return xml_get_syscalls_by_name (gdbarch, syscall_name, syscall_numbers);
}
const char **
/* See comment in xml-syscall.h. */
-struct syscall *
-get_syscalls_by_group (struct gdbarch *gdbarch, const char *group)
+bool
+get_syscalls_by_group (struct gdbarch *gdbarch, const char *group,
+ std::vector<int> *syscall_numbers)
{
init_syscalls_info (gdbarch);
- return xml_list_syscalls_by_group (gdbarch, group);
+ return xml_list_syscalls_by_group (gdbarch, group, syscall_numbers);
}
/* See comment in xml-syscall.h. */