Message ID | 1357601496-31718-1-git-send-email-Alex_Rozenman@mentor.com |
---|---|
State | New |
Headers | show |
On Tue, Jan 08, 2013 at 01:31:36AM +0200, Alex Rozenman wrote: > Signed-off-by: Alex Rozenman <Alex_Rozenman@mentor.com> > --- > 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 > >
On Mon, Jan 7, 2013 at 11:31 PM, Alex Rozenman <Alex_Rozenman@mentor.com> wrote: > Signed-off-by: Alex Rozenman <Alex_Rozenman@mentor.com> > --- > gdbstub.c | 113 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 113 insertions(+) > > 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. */ The line is malformed, according to the coding style, it should be if (*p != ':') { return 0; } > + 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. */ Also here and several other places. Please fix. > + *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); I'm not sure this message will be useful for the user, how about using qemu_log(LOG_UNIMP,...)? > + 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); Please use snprintf(). > + 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 > >
On 2013-01-09 09:50, Stefan Hajnoczi wrote: > On Tue, Jan 08, 2013 at 01:31:36AM +0200, Alex Rozenman wrote: >> Signed-off-by: Alex Rozenman <Alex_Rozenman@mentor.com> >> --- >> 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 */ I do not find what you implement here on that website or in gdb's git. Is there an even more recent version? Is that protocol actually approved already? Jan >> + 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 >> >>
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. */
Signed-off-by: Alex Rozenman <Alex_Rozenman@mentor.com> --- gdbstub.c | 113 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+)