diff mbox

gdbstub: Implement Xfer:auxv:read

Message ID 1435748420-4000-1-git-send-email-bhushan.attarde@imgtec.com
State New
Headers show

Commit Message

Bhushan Attarde July 1, 2015, 11 a.m. UTC
Implementation of "Xfer:auxv:read" to provide auxiliary vector information
to clients which relies on it.

For example: AT_ENTRY in auxiliary vector provides the entry point information.
Client can use this information to compare it with entry point mentioned in
executable to calculate load offset and then update the load addresses
accordingly.

Signed-off-by: Bhushan Attarde <bhushan.attarde@imgtec.com>
---
 gdbstub.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 47 insertions(+)

Comments

Peter Maydell July 14, 2015, 7:46 p.m. UTC | #1
On 1 July 2015 at 12:00, Bhushan Attarde <bhushan.attarde@imgtec.com> wrote:
> Implementation of "Xfer:auxv:read" to provide auxiliary vector information
> to clients which relies on it.
>
> For example: AT_ENTRY in auxiliary vector provides the entry point information.
> Client can use this information to compare it with entry point mentioned in
> executable to calculate load offset and then update the load addresses
> accordingly.
>
> Signed-off-by: Bhushan Attarde <bhushan.attarde@imgtec.com>
> ---
>  gdbstub.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 47 insertions(+)
>
> diff --git a/gdbstub.c b/gdbstub.c
> index cea2a84..bdcaa6b 100644
> --- a/gdbstub.c
> +++ b/gdbstub.c
> @@ -1153,6 +1153,9 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
>              if (cc->gdb_core_xml_file != NULL) {
>                  pstrcat(buf, sizeof(buf), ";qXfer:features:read+");
>              }
> +#ifdef CONFIG_USER_ONLY
> +            pstrcat(buf, sizeof(buf), ";qXfer:auxv:read+");
> +#endif
>              put_packet(s, buf);
>              break;
>          }
> @@ -1199,6 +1202,50 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
>              put_packet_binary(s, buf, len + 1);
>              break;
>          }
> +#ifdef CONFIG_USER_ONLY
> +        if (strncmp(p, "Xfer:auxv:read:", 15) == 0) {
> +            TaskState *ts = s->c_cpu->opaque;
> +            target_ulong auxv = ts->info->saved_auxv;
> +            target_ulong auxv_len = ts->info->auxv_len;
> +            char *ptr;
> +
> +            p += 15;
> +            while (*p && *p != ':') {
> +                p++;
> +            }
> +            p++;
> +
> +            addr = strtoul(p, (char **)&p, 16);
> +            if (*p == ',') {
> +                p++;
> +            }
> +            len = strtoul(p, (char **)&p, 16);
> +
> +            ptr = lock_user(VERIFY_READ, auxv, auxv_len, 0);
> +            if (ptr == NULL) {
> +                break;
> +            }
> +
> +            if (addr > len) {
> +                snprintf(buf, sizeof(buf), "E00");
> +                put_packet(s, buf);
> +                break;
> +            }
> +            if (len > (MAX_PACKET_LENGTH - 5) / 2) {
> +                len = (MAX_PACKET_LENGTH - 5) / 2;
> +            }
> +            if (len < auxv_len - addr) {
> +                buf[0] = 'm';
> +                len = memtox(buf + 1, ptr + addr, len);
> +            } else {
> +                buf[0] = 'l';
> +                len = memtox(buf + 1, ptr + addr, auxv_len - addr);
> +            }

The bulk of this code for parsing out the arguments in a
qXfer:OBJECT:read:ANNEX:OFFSET,LENGTH packet is identical
to that we already have for handling Xfer:features:read.
We should factor this out neatly rather than duplicating it.

thanks
-- PMM
diff mbox

Patch

diff --git a/gdbstub.c b/gdbstub.c
index cea2a84..bdcaa6b 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -1153,6 +1153,9 @@  static int gdb_handle_packet(GDBState *s, const char *line_buf)
             if (cc->gdb_core_xml_file != NULL) {
                 pstrcat(buf, sizeof(buf), ";qXfer:features:read+");
             }
+#ifdef CONFIG_USER_ONLY
+            pstrcat(buf, sizeof(buf), ";qXfer:auxv:read+");
+#endif
             put_packet(s, buf);
             break;
         }
@@ -1199,6 +1202,50 @@  static int gdb_handle_packet(GDBState *s, const char *line_buf)
             put_packet_binary(s, buf, len + 1);
             break;
         }
+#ifdef CONFIG_USER_ONLY
+        if (strncmp(p, "Xfer:auxv:read:", 15) == 0) {
+            TaskState *ts = s->c_cpu->opaque;
+            target_ulong auxv = ts->info->saved_auxv;
+            target_ulong auxv_len = ts->info->auxv_len;
+            char *ptr;
+
+            p += 15;
+            while (*p && *p != ':') {
+                p++;
+            }
+            p++;
+
+            addr = strtoul(p, (char **)&p, 16);
+            if (*p == ',') {
+                p++;
+            }
+            len = strtoul(p, (char **)&p, 16);
+
+            ptr = lock_user(VERIFY_READ, auxv, auxv_len, 0);
+            if (ptr == NULL) {
+                break;
+            }
+
+            if (addr > len) {
+                snprintf(buf, sizeof(buf), "E00");
+                put_packet(s, buf);
+                break;
+            }
+            if (len > (MAX_PACKET_LENGTH - 5) / 2) {
+                len = (MAX_PACKET_LENGTH - 5) / 2;
+            }
+            if (len < auxv_len - addr) {
+                buf[0] = 'm';
+                len = memtox(buf + 1, ptr + addr, len);
+            } else {
+                buf[0] = 'l';
+                len = memtox(buf + 1, ptr + addr, auxv_len - addr);
+            }
+            put_packet_binary(s, buf, len + 1);
+            unlock_user(ptr, auxv, len);
+            break;
+        }
+#endif /* !CONFIG_USER_ONLY */
         if (is_query_packet(p, "Attached", ':')) {
             put_packet(s, GDB_ATTACHED);
             break;