summaryrefslogtreecommitdiff
path: root/gdb/xml-tdesc.c
diff options
context:
space:
mode:
authorDaniel Jacobowitz <dan@debian.org>2007-01-09 22:55:10 +0000
committerDaniel Jacobowitz <dan@debian.org>2007-01-09 22:55:10 +0000
commit240170fee8fed4d2b04720b3436166b35c9e52d9 (patch)
tree9974a009c7ddf77b8880d3a353b78f298a73fab6 /gdb/xml-tdesc.c
parent10040d74611aa76aad6e33bcf6621d4b66e1fed1 (diff)
downloadgdb-240170fee8fed4d2b04720b3436166b35c9e52d9.tar.gz
XML feature description support.
* NEWS: Mention target descriptions, "set tdesc filename", "unset tdesc filename", "show tdesc filename", and qXfer:features:read. * arch-utils.c (choose_architecture_for_target): New function. (gdbarch_info_fill): Call it. * target-descriptions.c (struct property): Make members non-const. (struct target_desc): Add arch member. (target_description_filename): New variable. (target_find_description): Try via XML first. (tdesc_architecture): New. (free_target_description, make_cleanup_free_target_description): New. (set_tdesc_property): Call xstrdup. (set_tdesc_architecture, tdesc_set_cmdlist, tdesc_show_cmdlist) (tdesc_unset_cmdlist, unset_tdesc_cmd, unset_tdesc_filename_cmd) (set_tdesc_cmd, show_tdesc_cmd, set_tdesc_filename_cmd) (show_tdesc_filename_cmd, _initialize_target_descriptions): New. * target-descriptions.h (tdesc_architecture) (make_cleanup_free_target_description, set_tdesc_architecture): New prototypes. * Makefile.in (SFILES): Add xml-tdesc.c. (COMMON_OBS): Add xml-tdesc.o. (target-descriptions.o): Update. (xml-tdesc.o): New rule. * xml-tdesc.c, xml-tdesc.h: New files. * remote.c (PACKET_qXfer_features): New enum. (remote_protocol_features): Add qXfer:features:read. (remote_xfer_partial): Handle TARGET_OBJECT_AVAILABLE_FEATURES. (_initialize_remote): Register qXfer:features:read. * target.h (enum target_object): Add TARGET_OBJECT_AVAILABLE_FEATURES. * features/gdb-target.dtd: New file. * linux-i386-low.c (the_low_target): Set arch_string. * linux-x86-64-low.c (the_low_target): Likewise. * linux-low.c (linux_arch_string): New. (linux_target_ops): Add it. * linux-low.h (struct linux_target_ops): Add arch_string. * server.c (write_qxfer_response): Use const void * for DATA. (get_features_xml): New. (handle_query): Handle qXfer:features:read. Report it for qSupported. * target.h (struct target_ops): Add arch_string method. * gdb.texinfo (Target Descriptions): New section. (General Query Packets): Add QPassSignals anchor. Mention qXfer:features:read under qSupported. Expand mentions of qXfer:memory-map:read and QPassSignals. Document qXfer:features:read.
Diffstat (limited to 'gdb/xml-tdesc.c')
-rw-r--r--gdb/xml-tdesc.c233
1 files changed, 233 insertions, 0 deletions
diff --git a/gdb/xml-tdesc.c b/gdb/xml-tdesc.c
new file mode 100644
index 00000000000..f47e3687b81
--- /dev/null
+++ b/gdb/xml-tdesc.c
@@ -0,0 +1,233 @@
+/* XML target description support for GDB.
+
+ Copyright (C) 2006
+ Free Software Foundation, Inc.
+
+ Contributed by CodeSourcery.
+
+ 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 2 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, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA. */
+
+#include "defs.h"
+#include "target.h"
+#include "target-descriptions.h"
+#include "xml-support.h"
+#include "xml-tdesc.h"
+
+#include "gdb_assert.h"
+
+#if !defined(HAVE_LIBEXPAT)
+
+/* Parse DOCUMENT into a target description. Or don't, since we don't have
+ an XML parser. */
+
+static struct target_desc *
+tdesc_parse_xml (const char *document)
+{
+ static int have_warned;
+
+ if (!have_warned)
+ {
+ have_warned = 1;
+ warning (_("Can not parse XML target description; XML support was "
+ "disabled at compile time"));
+ }
+
+ return NULL;
+}
+
+#else /* HAVE_LIBEXPAT */
+
+/* Callback data for target description parsing. */
+
+struct tdesc_parsing_data
+{
+ /* The target description we are building. */
+ struct target_desc *tdesc;
+};
+
+/* Handle the end of an <architecture> element and its value. */
+
+static void
+tdesc_end_arch (struct gdb_xml_parser *parser,
+ const struct gdb_xml_element *element,
+ void *user_data, const char *body_text)
+{
+ struct tdesc_parsing_data *data = user_data;
+ const struct bfd_arch_info *arch;
+
+ arch = bfd_scan_arch (body_text);
+ if (arch == NULL)
+ gdb_xml_error (parser, _("Target description specified unknown "
+ "architecture \"%s\""), body_text);
+ set_tdesc_architecture (data->tdesc, arch);
+}
+
+/* The elements and attributes of an XML target description. */
+
+const struct gdb_xml_element target_children[] = {
+ { "architecture", NULL, NULL, GDB_XML_EF_OPTIONAL,
+ NULL, tdesc_end_arch },
+ { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
+};
+
+const struct gdb_xml_element tdesc_elements[] = {
+ { "target", NULL, target_children, GDB_XML_EF_NONE,
+ NULL, NULL },
+ { NULL, NULL, NULL, GDB_XML_EF_NONE, NULL, NULL }
+};
+
+/* Parse DOCUMENT into a target description and return it. */
+
+static struct target_desc *
+tdesc_parse_xml (const char *document)
+{
+ struct cleanup *back_to, *result_cleanup;
+ struct gdb_xml_parser *parser;
+ struct tdesc_parsing_data data;
+
+ memset (&data, 0, sizeof (struct tdesc_parsing_data));
+
+ back_to = make_cleanup (null_cleanup, NULL);
+ parser = gdb_xml_create_parser_and_cleanup (_("target description"),
+ tdesc_elements, &data);
+
+ data.tdesc = allocate_target_description ();
+ result_cleanup = make_cleanup_free_target_description (data.tdesc);
+
+ if (gdb_xml_parse (parser, document) == 0)
+ {
+ /* Parsed successfully. */
+ discard_cleanups (result_cleanup);
+ do_cleanups (back_to);
+ return data.tdesc;
+ }
+ else
+ {
+ warning (_("Could not load XML target description; ignoring"));
+ do_cleanups (back_to);
+ return NULL;
+ }
+}
+
+#endif /* HAVE_LIBEXPAT */
+
+
+/* Close FILE. */
+
+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)
+{
+ FILE *file;
+ struct cleanup *back_to;
+ char *text;
+ size_t len, offset;
+
+ file = fopen (filename, FOPEN_RT);
+ if (file == NULL)
+ {
+ warning (_("Could not open \"%s\""), filename);
+ 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;
+}
+
+/* Read an XML target description from FILENAME. Parse it, and return
+ the parsed description. */
+
+const struct target_desc *
+file_read_description_xml (const char *filename)
+{
+ struct target_desc *tdesc;
+ char *tdesc_str;
+ struct cleanup *back_to;
+
+ tdesc_str = fetch_xml_from_file (filename);
+ if (tdesc_str == NULL)
+ return NULL;
+
+ back_to = make_cleanup (xfree, tdesc_str);
+ tdesc = tdesc_parse_xml (tdesc_str);
+ do_cleanups (back_to);
+
+ return tdesc;
+}
+
+/* Read an XML target description using OPS. Parse it, and return the
+ parsed description. */
+
+const struct target_desc *
+target_read_description_xml (struct target_ops *ops)
+{
+ struct target_desc *tdesc;
+ char *tdesc_str;
+ struct cleanup *back_to;
+
+ tdesc_str = target_read_stralloc (ops, TARGET_OBJECT_AVAILABLE_FEATURES,
+ "target.xml");
+ if (tdesc_str == NULL)
+ return NULL;
+
+ back_to = make_cleanup (xfree, tdesc_str);
+ tdesc = tdesc_parse_xml (tdesc_str);
+ do_cleanups (back_to);
+
+ return tdesc;
+}