aboutsummaryrefslogtreecommitdiff
path: root/gdb/gdbserver
diff options
context:
space:
mode:
authorDaniel Jacobowitz <drow@false.org>2007-01-09 22:55:10 +0000
committerDaniel Jacobowitz <drow@false.org>2007-01-09 22:55:10 +0000
commit23181151a2399f4ecbc272cda73172a078d1b435 (patch)
treeea2a6e528a8ea59c2af185ebd8e1d1c7c08d7a55 /gdb/gdbserver
parent3e9cb5f4b2410bf5b0e0659dbeb532f08c2963de (diff)
downloadgdb-23181151a2399f4ecbc272cda73172a078d1b435.zip
gdb-23181151a2399f4ecbc272cda73172a078d1b435.tar.gz
gdb-23181151a2399f4ecbc272cda73172a078d1b435.tar.bz2
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/gdbserver')
-rw-r--r--gdb/gdbserver/ChangeLog12
-rw-r--r--gdb/gdbserver/linux-i386-low.c6
-rw-r--r--gdb/gdbserver/linux-low.c7
-rw-r--r--gdb/gdbserver/linux-low.h4
-rw-r--r--gdb/gdbserver/linux-x86-64-low.c6
-rw-r--r--gdb/gdbserver/server.c69
-rw-r--r--gdb/gdbserver/target.h4
7 files changed, 107 insertions, 1 deletions
diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog
index 2035473..8336eca 100644
--- a/gdb/gdbserver/ChangeLog
+++ b/gdb/gdbserver/ChangeLog
@@ -1,3 +1,15 @@
+2007-01-09 Daniel Jacobowitz <dan@codesourcery.com>
+
+ * 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.
+
2007-01-03 Denis Pilat <denis.pilat@st.com>
Daniel Jacobowitz <dan@codesourcery.com>
diff --git a/gdb/gdbserver/linux-i386-low.c b/gdb/gdbserver/linux-i386-low.c
index 4710773..10c0ef0 100644
--- a/gdb/gdbserver/linux-i386-low.c
+++ b/gdb/gdbserver/linux-i386-low.c
@@ -198,4 +198,10 @@ struct linux_target_ops the_low_target = {
NULL,
1,
i386_breakpoint_at,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ 0,
+ "i386"
};
diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c
index eb8ef48..1d49593 100644
--- a/gdb/gdbserver/linux-low.c
+++ b/gdb/gdbserver/linux-low.c
@@ -1641,6 +1641,12 @@ linux_read_offsets (CORE_ADDR *text_p, CORE_ADDR *data_p)
}
#endif
+static const char *
+linux_arch_string (void)
+{
+ return the_low_target.arch_string;
+}
+
static struct target_ops linux_target_ops = {
linux_create_inferior,
linux_attach,
@@ -1670,6 +1676,7 @@ static struct target_ops linux_target_ops = {
#else
NULL,
#endif
+ linux_arch_string,
};
static void
diff --git a/gdb/gdbserver/linux-low.h b/gdb/gdbserver/linux-low.h
index aa0102b..aa3bfe1 100644
--- a/gdb/gdbserver/linux-low.h
+++ b/gdb/gdbserver/linux-low.h
@@ -71,6 +71,10 @@ struct linux_target_ops
/* Whether to left-pad registers for PEEKUSR/POKEUSR if they are smaller
than an xfer unit. */
int left_pad_xfer;
+
+ /* What string to report to GDB when it asks for the architecture,
+ or NULL not to answer. */
+ const char *arch_string;
};
extern struct linux_target_ops the_low_target;
diff --git a/gdb/gdbserver/linux-x86-64-low.c b/gdb/gdbserver/linux-x86-64-low.c
index 81c92fe..5951104 100644
--- a/gdb/gdbserver/linux-x86-64-low.c
+++ b/gdb/gdbserver/linux-x86-64-low.c
@@ -172,4 +172,10 @@ struct linux_target_ops the_low_target = {
NULL,
1,
x86_64_breakpoint_at,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ 0,
+ "i386:x86-64",
};
diff --git a/gdb/gdbserver/server.c b/gdb/gdbserver/server.c
index 1f78cce..20d47c9 100644
--- a/gdb/gdbserver/server.c
+++ b/gdb/gdbserver/server.c
@@ -145,7 +145,7 @@ decode_xfer_read (char *buf, char **annex, CORE_ADDR *ofs, unsigned int *len)
to as much of DATA/LEN as we could fit. IS_MORE controls
the first character of the response. */
static int
-write_qxfer_response (char *buf, unsigned char *data, int len, int is_more)
+write_qxfer_response (char *buf, const void *data, int len, int is_more)
{
int out_len;
@@ -192,6 +192,31 @@ handle_general_set (char *own_buf)
own_buf[0] = 0;
}
+static const char *
+get_features_xml (void)
+{
+ static int features_supported = -1;
+ static char *document;
+
+ if (features_supported == -1)
+ {
+ const char *arch = (*the_target->arch_string) ();
+
+ if (arch == NULL)
+ features_supported = 0;
+ else
+ {
+ features_supported = 1;
+ document = malloc (64 + strlen (arch));
+ snprintf (document, 64 + strlen (arch),
+ "<target><architecture>%s</architecture></target>",
+ arch);
+ }
+ }
+
+ return document;
+}
+
/* Handle all of the extended 'q' packets. */
void
handle_query (char *own_buf, int *new_packet_len_p)
@@ -279,6 +304,45 @@ handle_query (char *own_buf, int *new_packet_len_p)
return;
}
+ if (strncmp ("qXfer:features:read:", own_buf, 20) == 0)
+ {
+ CORE_ADDR ofs;
+ unsigned int len, total_len;
+ const char *document;
+ char *annex;
+
+ document = get_features_xml ();
+ if (document == NULL)
+ {
+ own_buf[0] = '\0';
+ return;
+ }
+
+ /* Reject any annex other than target.xml; grab the offset and
+ length. */
+ if (decode_xfer_read (own_buf + 20, &annex, &ofs, &len) < 0
+ || strcmp (annex, "target.xml") != 0)
+ {
+ strcpy (own_buf, "E00");
+ return;
+ }
+
+ total_len = strlen (document);
+ if (len > PBUFSIZ - 2)
+ len = PBUFSIZ - 2;
+
+ if (ofs > total_len)
+ write_enn (own_buf);
+ else if (len < total_len - ofs)
+ *new_packet_len_p = write_qxfer_response (own_buf, document + ofs,
+ len, 1);
+ else
+ *new_packet_len_p = write_qxfer_response (own_buf, document + ofs,
+ total_len - ofs, 0);
+
+ return;
+ }
+
/* Protocol features query. */
if (strncmp ("qSupported", own_buf, 10) == 0
&& (own_buf[10] == ':' || own_buf[10] == '\0'))
@@ -288,6 +352,9 @@ handle_query (char *own_buf, int *new_packet_len_p)
if (the_target->read_auxv != NULL)
strcat (own_buf, ";qXfer:auxv:read+");
+ if (get_features_xml () != NULL)
+ strcat (own_buf, ";qXfer:features:read+");
+
return;
}
diff --git a/gdb/gdbserver/target.h b/gdb/gdbserver/target.h
index 17137dc..d6e2655 100644
--- a/gdb/gdbserver/target.h
+++ b/gdb/gdbserver/target.h
@@ -171,6 +171,10 @@ struct target_ops
int (*get_tls_address) (struct thread_info *thread, CORE_ADDR offset,
CORE_ADDR load_module, CORE_ADDR *address);
+
+ /* Return a string identifying the current architecture, or NULL if
+ this operation is not supported. */
+ const char *(*arch_string) (void);
};
extern struct target_ops *the_target;