From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 20421 invoked by alias); 4 Nov 2008 04:32:44 -0000 Received: (qmail 19709 invoked by uid 22791); 4 Nov 2008 04:32:36 -0000 X-Spam-Check-By: sourceware.org Received: from igw3.br.ibm.com (HELO igw3.br.ibm.com) (32.104.18.26) by sourceware.org (qpsmtpd/0.31) with ESMTP; Tue, 04 Nov 2008 04:31:39 +0000 Received: from d24relay01.br.ibm.com (unknown [9.8.31.16]) by igw3.br.ibm.com (Postfix) with ESMTP id 22F4F39005E for ; Tue, 4 Nov 2008 02:30:06 -0200 (BRDT) Received: from d24av01.br.ibm.com (d24av01.br.ibm.com [9.18.232.46]) by d24relay01.br.ibm.com (8.13.8/8.13.8/NCO v9.1) with ESMTP id mA44VDGO3711078 for ; Tue, 4 Nov 2008 01:31:13 -0300 Received: from d24av01.br.ibm.com (loopback [127.0.0.1]) by d24av01.br.ibm.com (8.12.11.20060308/8.13.3) with ESMTP id mA44VXIR010427 for ; Tue, 4 Nov 2008 02:31:33 -0200 Received: from [9.18.200.192] ([9.18.200.192]) by d24av01.br.ibm.com (8.12.11.20060308/8.12.11) with ESMTP id mA44VXd6010411 for ; Tue, 4 Nov 2008 02:31:33 -0200 Subject: [PATCH 3/4] 'catch syscall' feature -- XML support part From: =?ISO-8859-1?Q?S=E9rgio?= Durigan =?ISO-8859-1?Q?J=FAnior?= To: gdb-patches@sourceware.org Content-Type: multipart/mixed; boundary="=-zTxET148rr+bPR91sUZI" Date: Tue, 04 Nov 2008 04:32:00 -0000 Message-Id: <1225773086.24532.55.camel@miki> Mime-Version: 1.0 X-Mailer: Evolution 2.22.3.1 X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2008-11/txt/msg00020.txt.bz2 --=-zTxET148rr+bPR91sUZI Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 8bit Content-length: 776 This is the part which adds XML support for the "catch syscall" feature. I decided to put the architecture's XML files here too, so that the architecture-independent part does not grow too much. Regards, -- Sérgio Durigan Júnior Linux on Power Toolchain - Software Engineer Linux Technology Center - LTC IBM Brazil gdb/ChangeLog: 2008-11-04 Sergio Durigan Junior * gdb-syscalls.dtd: New definition file for syscall's XML support. * i386-syscalls.xml: New file for i386 syscalls. * ppc-syscalls.xml: New file for PPC syscalls. * ppc64-syscalls.xml: New file for PPC64 syscalls. * xml-syscall.c: New file containing functions for manipulating syscall's XML files. * xml-syscall.h: New file, exporting the functions above mentioned. --=-zTxET148rr+bPR91sUZI Content-Disposition: attachment; filename=catch-syscall-xml-support.patch Content-Type: text/x-patch; name=catch-syscall-xml-support.patch; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Content-length: 55536 diff --git a/gdb/syscalls/gdb-syscalls.dtd b/gdb/syscalls/gdb-syscalls.dtd new file mode 100644 index 0000000..0d40ab4 --- /dev/null +++ b/gdb/syscalls/gdb-syscalls.dtd @@ -0,0 +1,21 @@ + + + + + + + + + + + + diff --git a/gdb/syscalls/i386-syscalls.xml b/gdb/syscalls/i386-syscalls.xml new file mode 100644 index 0000000..8044c7b --- /dev/null +++ b/gdb/syscalls/i386-syscalls.xml @@ -0,0 +1,337 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gdb/syscalls/ppc-syscalls.xml b/gdb/syscalls/ppc-syscalls.xml new file mode 100644 index 0000000..4ac794f --- /dev/null +++ b/gdb/syscalls/ppc-syscalls.xml @@ -0,0 +1,312 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gdb/syscalls/ppc64-syscalls.xml b/gdb/syscalls/ppc64-syscalls.xml new file mode 100644 index 0000000..2795de0 --- /dev/null +++ b/gdb/syscalls/ppc64-syscalls.xml @@ -0,0 +1,306 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gdb/xml-syscall.c b/gdb/xml-syscall.c new file mode 100644 index 0000000..8f16752 --- /dev/null +++ b/gdb/xml-syscall.c @@ -0,0 +1,438 @@ +/* Functions that provide the mechanism to parse a syscall XML file + and get its values. + + Copyright (C) 1986, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, + 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, 2007, 2008 + 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 . */ + +#include "defs.h" +#include "gdbtypes.h" +#include "xml-support.h" +#include "xml-syscall.h" + +#include "filenames.h" + +#include "gdb_assert.h" + +#ifndef HAVE_LIBEXPAT + +/* Dummy functions to indicate that there's no support for fetching + syscalls information. */ + +static void +syscall_warn_user (void) +{ + static int have_warned = 0; + if (!have_warned) + { + have_warned = 1; + warning (_("Can not parse XML syscalls information; XML support was " + "disabled at compile time")); + } +} + +const struct syscalls_info * +xml_init_syscalls_info (const char *filename) +{ + syscall_warn_user (); + return NULL; +} + +int +xml_get_syscall_number (const struct syscalls_info *sysinfo, + const char *syscall_name) +{ + syscall_warn_user (); + return UNKNOWN_SYSCALL; +} + +const char * +xml_get_syscall_name (const struct syscalls_info *sysinfo, + int syscall_number) +{ + syscall_warn_user (); + return NULL; +} + +int +xml_number_of_syscalls (const struct syscalls_info *sysinfo) +{ + syscall_warn_user (); + return 0; +} + +const char ** +xml_list_of_syscalls (const struct syscalls_info *sysinfo) +{ + syscall_warn_user (); + return NULL; +} + +#else + +/* Structure which describes a syscall. */ + +typedef struct syscall_desc +{ + /* The syscall number. */ + + int number; + + /* The syscall name. */ + + char *name; +} *syscall_desc_p; +DEF_VEC_P(syscall_desc_p); + +/* Structure that represents syscalls information. */ + +struct syscalls_info +{ + /* The number of syscalls in this system. */ + + int number_of_syscalls; + + /* The syscalls. */ + + VEC(syscall_desc_p) *syscalls; +}; + +/* Callback data for syscall information parsing. */ + +struct syscall_parsing_data +{ + /* The syscalls_info we are building. */ + + struct syscalls_info *sysinfo; +}; + + +static struct syscalls_info * +allocate_syscalls_info (void) +{ + return XZALLOC (struct syscalls_info); +} + +static void +sysinfo_free_syscalls_desc (struct syscall_desc *sd) +{ + xfree (sd->name); +} + +static void +free_syscalls_info (void *arg) +{ + struct syscalls_info *sysinfo = arg; + struct syscall_desc *sysdesc; + int i; + + for (i = 0; + VEC_iterate (syscall_desc_p, sysinfo->syscalls, i, sysdesc); + i++) + sysinfo_free_syscalls_desc (sysdesc); + VEC_free (syscall_desc_p, sysinfo->syscalls); + + xfree (sysinfo); +} + +struct cleanup * +make_cleanup_free_syscalls_info (struct syscalls_info *sysinfo) +{ + return make_cleanup (free_syscalls_info, sysinfo); +} + +static void +do_cleanup_fclose (void *file) +{ + fclose (file); +} + +/* Open FILENAME, read all its text into memory, close it, and return + the text. If something goes wrong, return NULL and warn. */ + +static char * +fetch_xml_from_file (const char *filename, void *baton) +{ + const char *dirname = baton; + FILE *file; + struct cleanup *back_to; + char *text; + size_t len, offset; + + if (dirname && *dirname) + { + char *fullname = concat (dirname, "/", filename, (char *) NULL); + if (fullname == NULL) + nomem (0); + file = fopen (fullname, FOPEN_RT); + xfree (fullname); + } + else + file = fopen (filename, FOPEN_RT); + + if (file == NULL) + return NULL; + + back_to = make_cleanup (do_cleanup_fclose, file); + + /* Read in the whole file, one chunk at a time. */ + len = 4096; + offset = 0; + text = xmalloc (len); + make_cleanup (free_current_contents, &text); + while (1) + { + size_t bytes_read; + + /* Continue reading where the last read left off. Leave at least + one byte so that we can NUL-terminate the result. */ + bytes_read = fread (text + offset, 1, len - offset - 1, file); + if (ferror (file)) + { + warning (_("Read error from \"%s\""), filename); + do_cleanups (back_to); + return NULL; + } + + offset += bytes_read; + + if (feof (file)) + break; + + len = len * 2; + text = xrealloc (text, len); + } + + fclose (file); + discard_cleanups (back_to); + + text[offset] = '\0'; + return text; +} + +static void +syscall_create_syscall_desc (struct syscalls_info *sysinfo, + const char *name, int number) +{ + struct syscall_desc *sysdesc = XZALLOC (struct syscall_desc); + + sysdesc->name = xstrdup (name); + sysdesc->number = number; + + VEC_safe_push (syscall_desc_p, sysinfo->syscalls, sysdesc); +} + +/* Handle the start of a element. */ + +static void +syscall_start_syscalls_info (struct gdb_xml_parser *parser, + const struct gdb_xml_element *element, + void *user_data, + VEC(gdb_xml_value_s) *attributes) +{ + struct syscall_parsing_data *data = user_data; + struct syscalls_info *sysinfo = data->sysinfo; + + /* Initializing fields. */ + sysinfo->number_of_syscalls = 0; +} + +/* Handle the start of a element. */ + +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) +{ + struct syscall_parsing_data *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; + + len = VEC_length (gdb_xml_value_s, attributes); + + for (i = 0; i < len; i++) + { + if (strcmp (attrs[i].name, "name") == 0) + name = attrs[i].value; + else if (strcmp (attrs[i].name, "number") == 0) + number = * (ULONGEST *) attrs[i].value; + else + internal_error (__FILE__, __LINE__, + _("Unknown attribute name '%s'."), attrs[i].name); + } + + syscall_create_syscall_desc (data->sysinfo, name, number); + + data->sysinfo->number_of_syscalls++; +} + + +/* The elements and attributes of an XML syscall document. */ + +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 }, + { NULL, GDB_XML_AF_NONE, NULL, NULL } +}; + +static const struct gdb_xml_element syscalls_info_children[] = { + { "syscall", syscall_attr, NULL, + GDB_XML_EF_OPTIONAL | GDB_XML_EF_REPEATABLE, + syscall_start_syscall, NULL }, + { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL } +}; + +static const struct gdb_xml_element syselements[] = { + { "syscalls_info", NULL, syscalls_info_children, + GDB_XML_EF_NONE, syscall_start_syscalls_info, NULL }, + { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL } +}; + +static struct syscalls_info * +syscall_parse_xml (const char *document, xml_fetch_another fetcher, + void *fetcher_baton) +{ + struct cleanup *back_to, *result_cleanup; + struct gdb_xml_parser *parser; + struct syscall_parsing_data data; + char *expanded_text; + int i; + + back_to = make_cleanup (null_cleanup, NULL); + parser = gdb_xml_create_parser_and_cleanup (_("syscalls info"), + syselements, &data); + + memset (&data, 0, sizeof (struct syscall_parsing_data)); + data.sysinfo = allocate_syscalls_info (); + result_cleanup = make_cleanup_free_syscalls_info (data.sysinfo); + + if (gdb_xml_parse (parser, document) == 0) + { + /* Parsed successfully. */ + discard_cleanups (result_cleanup); + do_cleanups (back_to); + return data.sysinfo; + } + else + { + warning (_("Could not load XML syscalls info; ignoring")); + do_cleanups (back_to); + return NULL; + } +} + +const struct syscalls_info * +xml_init_syscalls_info (const char *filename) +{ + char *full_file; + char *dirname; + struct syscalls_info *sysinfo; + struct cleanup *back_to; + + full_file = fetch_xml_from_file (filename, gdb_datadir); + if (full_file == NULL) + { + warning (_("Could not open \"%s\""), filename); + return NULL; + } + + back_to = make_cleanup (xfree, full_file); + + dirname = ldirname (filename); + if (dirname != NULL) + make_cleanup (xfree, dirname); + + sysinfo = syscall_parse_xml (full_file, fetch_xml_from_file, dirname); + do_cleanups (back_to); + + return sysinfo; +} + +int +xml_get_syscall_number (const struct syscalls_info *sysinfo, + const char *syscall_name) +{ + struct syscall_desc *sysdesc; + int i; + + if (sysinfo == NULL + || syscall_name == NULL) + return UNKNOWN_SYSCALL; + + for (i = 0; + VEC_iterate(syscall_desc_p, sysinfo->syscalls, i, sysdesc); + i++) + if (strcmp (sysdesc->name, syscall_name) == 0) + return sysdesc->number; + + return UNKNOWN_SYSCALL; +} + +const char * +xml_get_syscall_name (const struct syscalls_info *sysinfo, + int syscall_number) +{ + struct syscall_desc *sysdesc; + int i; + + if (sysinfo == NULL + || syscall_number < 0 + || syscall_number >= sysinfo->number_of_syscalls) + return NULL; + + for (i = 0; + VEC_iterate(syscall_desc_p, sysinfo->syscalls, i, sysdesc); + i++) + if (sysdesc->number == syscall_number) + return sysdesc->name; + + return NULL; +} + +int +xml_number_of_syscalls (const struct syscalls_info *sysinfo) +{ + return (sysinfo == NULL ? 0 : sysinfo->number_of_syscalls); +} + +const char ** +xml_list_of_syscalls (const struct syscalls_info *sysinfo) +{ + struct syscall_desc *sysdesc; + const char **names = NULL; + int i; + + if (sysinfo == NULL) + return NULL; + + names = xmalloc ((sysinfo->number_of_syscalls + 1) * sizeof (char *)); + + for (i = 0; + VEC_iterate(syscall_desc_p, sysinfo->syscalls, i, sysdesc); + i++) + names[i] = xstrdup (sysdesc->name); + + names[i] = NULL; + + return names; +} + +#endif /* HAVE_LIBEXPAT */ diff --git a/gdb/xml-syscall.h b/gdb/xml-syscall.h new file mode 100644 index 0000000..ff11f20 --- /dev/null +++ b/gdb/xml-syscall.h @@ -0,0 +1,64 @@ +/* Functions that provide the mechanism to parse a syscall XML file + and get its values. + + Copyright (C) 1986, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, + 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, 2007, 2008 + 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 . */ + +#ifndef XML_SYSCALL_H +#define XML_SYSCALL_H 1 + +/* Structure that stores information about the system's + syscalls. */ + +struct syscalls_info; + + +/* Function responsible for initializing the information + about the syscalls. It reads the XML file and fills the + struct syscalls_info with the values. + + Returns the struct syscalls_info if the file is valid, NULL otherwise. */ + +const struct syscalls_info *xml_init_syscalls_info (const char *); + +/* Function that retrieves the syscall number corresponding to the given + name. + + Returns the syscall number if found, or otherwise. */ + +int xml_get_syscall_number (const struct syscalls_info *, const char *); + +/* Function that retrieves the syscall name corresponding to the given + number. + + Returns the syscall name if found, NULL otherwise. */ +const char *xml_get_syscall_name (const struct syscalls_info *, int); + +/* Function that returns the number of syscalls defined in the system. + + Returns the number of syscalls, or zero otherwise. */ +int xml_number_of_syscalls (const struct syscalls_info *); + +/* Function used to retrieve the list of syscalls in the system. This list + is returned as an array of strings. + + Returns the list of syscalls in the system, or NULL otherwise. */ +const char **xml_list_of_syscalls (const struct syscalls_info *sysinfo); + +#endif /* XML_SYSCALL_H */ --=-zTxET148rr+bPR91sUZI--