diff options
Diffstat (limited to 'gdb/gdbserver')
-rw-r--r-- | gdb/gdbserver/ChangeLog | 12 | ||||
-rw-r--r-- | gdb/gdbserver/linux-i386-low.c | 6 | ||||
-rw-r--r-- | gdb/gdbserver/linux-low.c | 7 | ||||
-rw-r--r-- | gdb/gdbserver/linux-low.h | 4 | ||||
-rw-r--r-- | gdb/gdbserver/linux-x86-64-low.c | 6 | ||||
-rw-r--r-- | gdb/gdbserver/server.c | 69 | ||||
-rw-r--r-- | gdb/gdbserver/target.h | 4 |
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; |