diff options
author | Pedro Alves <palves@redhat.com> | 2015-11-19 18:31:50 +0000 |
---|---|---|
committer | Pedro Alves <palves@redhat.com> | 2015-11-19 18:32:55 +0000 |
commit | 06e03fff313dfcc5f344280f8ac70b0ec8521f3a (patch) | |
tree | 87cfec6774afc96d69062e21c5087077b82e4c04 /gdb/gdbserver/server.c | |
parent | b35d5edb03798388d503d922d8f909a133bf93dd (diff) | |
download | fsf-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.c | 19 |
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); } |