aboutsummaryrefslogtreecommitdiff
path: root/gdb/gdbserver
diff options
context:
space:
mode:
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;