From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([208.118.235.92]:39018) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TsrN9-0004WN-KZ for qemu-devel@nongnu.org; Wed, 09 Jan 2013 03:50:57 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1TsrN7-0005IP-Pd for qemu-devel@nongnu.org; Wed, 09 Jan 2013 03:50:55 -0500 Received: from mail-bk0-f50.google.com ([209.85.214.50]:62490) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TsrN7-0005IC-Es for qemu-devel@nongnu.org; Wed, 09 Jan 2013 03:50:53 -0500 Received: by mail-bk0-f50.google.com with SMTP id jf3so733500bkc.37 for ; Wed, 09 Jan 2013 00:50:52 -0800 (PST) Date: Wed, 9 Jan 2013 09:50:50 +0100 From: Stefan Hajnoczi Message-ID: <20130109085050.GD30476@stefanha-thinkpad.redhat.com> References: <1357601496-31718-1-git-send-email-Alex_Rozenman@mentor.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1357601496-31718-1-git-send-email-Alex_Rozenman@mentor.com> Subject: Re: [Qemu-devel] [PATCH] gdbstub: Implement "Xfer:spaces" requests. This is a part of Codebench IDE integration. List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Alex Rozenman Cc: Peter Maydell , Anthony Liguori , Vladimir Pilko , Jan Kiszka , Alex Rozenman , qemu-devel@nongnu.org, Paul Brook On Tue, Jan 08, 2013 at 01:31:36AM +0200, Alex Rozenman wrote: > Signed-off-by: Alex Rozenman > --- > gdbstub.c | 113 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 113 insertions(+) Also worth CCing Jan Kiszka on gdbstub changes. > diff --git a/gdbstub.c b/gdbstub.c > index a8dd437..564bde1 100644 > --- a/gdbstub.c > +++ b/gdbstub.c > @@ -1839,6 +1839,90 @@ static const char *get_feature_xml(const char *p, const char **newp) > } > return name ? xml_builtin[i][1] : NULL; > } > + > +typedef struct XferSpaceReq { > + int is_write; > + char annex[32]; > + uint64_t offset; > + unsigned length; > + char* data; /* Data buffer for write. */ > +} XferSpaceReq; > + > +static int remote_unescape_input(const char* begin, const char* end, char* out) > +{ > + int escaped = 0; > + const char *p, *out_begin = out; > + for (p = begin; p != end; ++p) { > + char b = *p; > + if (escaped) { > + *out++ = b ^ 0x20; > + escaped = 0; > + } else if (b == '}') { > + escaped = 1; > + } else { > + *out++ = b; > + } > + } > + if (escaped) { > + fprintf(stderr, "Unmatched escape character in target response.\n"); > + } > + return out - out_begin; > +} > + > +static int parse_xfer_spaces_req(const char* begin, const char* end, XferSpaceReq* req) > +{ > + const char *p; > + char *out, *limit; > + > + p = begin; > + > + /* Read read/write word. */ > + if (strncmp(p, "read", 4) == 0) { > + req->is_write = 0; > + p += 4; > + } else if (strncmp(p, "write", 5) == 0) { > + req->is_write = 1; > + p += 5; > + } else { > + return 0; /* Malformed. */ > + } > + > + /* Consume the next colon. */ > + if (*p != ':') return 0; /* Malformed. */ > + p++; > + > + /* Read the annex designator. */ > + out = req->annex; > + limit = out + sizeof(req->annex); > + while (*p != ':' && out != limit) { > + *out++ = *p++; > + } > + if (out == limit) return 0; /* Too long. */ > + *out = (char)0; > + > + /* Consume the next colon. */ > + if (*p != ':') return 0; /* Malformed. */ > + p++; > + > + /* Read the offset */ > + req->offset = strtoul(p, (char **)&p, 16); > + > + if (req->is_write) { > + if (*p != ':') return 0; /* Should be colon. */ > + p++; > + req->length = remote_unescape_input(p, end, req->data); > + } else { > + if (*p != ',') return 0; /* Should be comma. */ > + p++; > + /* Read the length */ > + req->length = strtoul(p, (char **)&p, 16); > + if (!req->length) return 0; /* Zero length request. */ > + } > + > + return 1; > +} > + > + > #endif > > static int gdb_read_register(CPUArchState *env, uint8_t *mem_buf, int reg) > @@ -2467,6 +2551,35 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf) > } > put_packet_binary(s, buf, len + 1); > break; > + } else if (strncmp(p, "Xfer:spaces:", 12) == 0) { > + /* The following code is implemented according to: > + http://sourceware.org/gdb/onlinedocs/gdb/General-Query-Packets.html */ > + XferSpaceReq req; > + req.data = (char*)mem_buf; > + if (!parse_xfer_spaces_req(p + 12, s->line_buf + s->line_buf_index, &req)) { > + fprintf(stderr, "gdbstub: Malformed Xfer '%s'\n", p); > + put_packet(s, "E00"); > + break; > + } > + if (strcmp(req.annex, "memory") != 0) { > + /* Only annex "memory" is currently supported. */ > + put_packet(s, "E14"); > + break; > + } > + if (target_memory_rw_debug(s->g_cpu, req.offset, mem_buf, req.length, > + req.is_write) != 0) { > + put_packet(s, "E14"); > + break; > + } > + if (req.is_write) { > + sprintf(buf, "%02X", req.length); > + put_packet(s, buf); > + } else { > + buf[0] = 'm'; > + memtox(buf + 1, (const char*)mem_buf, req.length); > + put_packet_binary(s, buf, req.length + 1); > + } > + break; > } > #endif > /* Unrecognised 'q' command. */ > -- > 1.7.9.6 > >