aboutsummaryrefslogtreecommitdiff
path: root/gdb/gdbserver/server.c
diff options
context:
space:
mode:
authorPedro Alves <palves@redhat.com>2015-11-19 18:31:50 +0000
committerPedro Alves <palves@redhat.com>2015-11-19 18:32:55 +0000
commit06e03fff313dfcc5f344280f8ac70b0ec8521f3a (patch)
tree87cfec6774afc96d69062e21c5087077b82e4c04 /gdb/gdbserver/server.c
parentb35d5edb03798388d503d922d8f909a133bf93dd (diff)
downloadfsf-binutils-gdb-06e03fff313dfcc5f344280f8ac70b0ec8521f3a.zip
fsf-binutils-gdb-06e03fff313dfcc5f344280f8ac70b0ec8521f3a.tar.gz
fsf-binutils-gdb-06e03fff313dfcc5f344280f8ac70b0ec8521f3a.tar.bz2
gdbserver: Fix qSupported:xmlRegisters=i386;UnknownFeature+ handling
The target_process_qsupported method is called for each qSupported feature that the common code does not recognize. The only current implementation, for x86 Linux (x86_linux_process_qsupported), assumes that it either is called with the "xmlRegisters=i386" feature, or that it is isn't called at all, indicating the connected GDB predates x86 XML descriptions. That's a bad assumption however. If GDB sends in a new/unknown (to core gdbserver) feature after "xmlRegisters=i386", say, something like qSupported:xmlRegisters=i386;UnknownFeature+, then when target_process_qsupported is called for "UnknownFeature+", x86_linux_process_qsupported clears the 'use_xml' global and calls x86_linux_update_xmltarget, and gdbserver ends up _not_ reporting a XML description... This commit changes the target_process_qsupported API to instead pass down a vector of unprocessed qSupported features in one go. (There's an early call to target_process_qsupported(NULL) that indicates "starting qSupported processing". There's no matching call to mark the end of processing, though. I first fixed this by passing (char *)-1 to indicate that, and adjusted the x86 backend to only clear 'use_xml' when qSupported processing starts, and then only call x86_linux_update_xmltarget() when (char *)-1 was passed. However, I wasn't that happy with the hack and came up this alternative version.) gdb/gdbserver/ChangeLog: 2015-11-19 Pedro Alves <palves@redhat.com> * linux-low.c (linux_process_qsupported): Change prototype. Adjust. * linux-low.h (struct linux_target_ops) <process_qsupported>: Change prototype. * linux-x86-low.c (x86_linux_process_qsupported): Change prototype and adjust to loop over all features. * server.c (handle_query) <qSupported>: Adjust to call target_process_qsupported once, passing it a vector of unprocessed features. * target.h (struct target_ops) <process_qsupported>: Change prototype. (target_process_qsupported): Adjust.
Diffstat (limited to 'gdb/gdbserver/server.c')
-rw-r--r--gdb/gdbserver/server.c19
1 files changed, 13 insertions, 6 deletions
diff --git a/gdb/gdbserver/server.c b/gdb/gdbserver/server.c
index fd2804b..7d6c9cc 100644
--- a/gdb/gdbserver/server.c
+++ b/gdb/gdbserver/server.c
@@ -2054,9 +2054,6 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
char *p = &own_buf[10];
int gdb_supports_qRelocInsn = 0;
- /* Start processing qSupported packet. */
- target_process_qsupported (NULL);
-
/* Process each feature being provided by GDB. The first
feature will follow a ':', and latter features will follow
';'. */
@@ -2064,6 +2061,7 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
{
char **qsupported = NULL;
int count = 0;
+ int unknown = 0;
int i;
/* Two passes, to avoid nested strtok calls in
@@ -2128,11 +2126,20 @@ handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
else if (strcmp (p, "vContSupported+") == 0)
vCont_supported = 1;
else
- target_process_qsupported (p);
-
- free (p);
+ {
+ /* Move the unknown features all together. */
+ qsupported[i] = NULL;
+ qsupported[unknown] = p;
+ unknown++;
+ }
}
+ /* Give the target backend a chance to process the unknown
+ features. */
+ target_process_qsupported (qsupported, unknown);
+
+ for (i = 0; i < count; i++)
+ free (qsupported[i]);
free (qsupported);
}