diff mbox

gdbstub: Support AUXV packet for debugging PIE executables.

Message ID 5471E103.6080109@gmail.com
State New
Headers show

Commit Message

Wei-cheng Wang Nov. 23, 2014, 1:28 p.m. UTC
Hi,

This patch adds support for sending AUXV packet.
This is required for debugging Linux position independent executables.
Otherwise, gdb client cannot find out where the executable is loaded.

Signed-off-by: Wei-cheng, Wang <cole945@gmail.com>
---
  gdbstub.c | 41 +++++++++++++++++++++++++++++++++++++++++
  1 file changed, 41 insertions(+)

Comments

Paolo Bonzini Nov. 27, 2014, 4:57 p.m. UTC | #1
CCing Riku Voipio for a review.

Paolo

On 23/11/2014 14:28, Wei-cheng, Wang wrote:
> Hi,
> 
> This patch adds support for sending AUXV packet.
> This is required for debugging Linux position independent executables.
> Otherwise, gdb client cannot find out where the executable is loaded.
> 
> Signed-off-by: Wei-cheng, Wang <cole945@gmail.com>
> ---
>  gdbstub.c | 41 +++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 41 insertions(+)
> 
> diff --git a/gdbstub.c b/gdbstub.c
> index d1b5afd..30f3bbc 100644
> --- a/gdbstub.c
> +++ b/gdbstub.c
> @@ -1127,6 +1127,7 @@ 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+");
>              }
> +            pstrcat(buf, sizeof(buf), ";qXfer:auxv:read+");
>              put_packet(s, buf);
>              break;
>          }
> @@ -1173,6 +1174,46 @@ 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);
> +        }
> +#endif /* !CONFIG_USER_ONLY */
>          /* Unrecognised 'q' command.  */
>          goto unknown_command;
>
Wei-cheng Wang Dec. 25, 2014, 5:31 p.m. UTC | #2
Ping :)

Thanks,
Wei-cheng

On 11/28/2014 12:57 AM, Paolo Bonzini wrote:
> CCing Riku Voipio for a review.
>
> Paolo
>
> On 23/11/2014 14:28, Wei-cheng, Wang wrote:
>> Hi,
>>
>> This patch adds support for sending AUXV packet.
>> This is required for debugging Linux position independent executables.
>> Otherwise, gdb client cannot find out where the executable is loaded.
>>
>> Signed-off-by: Wei-cheng, Wang <cole945@gmail.com>
>> ---
>>   gdbstub.c | 41 +++++++++++++++++++++++++++++++++++++++++
>>   1 file changed, 41 insertions(+)
>>
>> diff --git a/gdbstub.c b/gdbstub.c
>> index d1b5afd..30f3bbc 100644
>> --- a/gdbstub.c
>> +++ b/gdbstub.c
>> @@ -1127,6 +1127,7 @@ 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+");
>>               }
>> +            pstrcat(buf, sizeof(buf), ";qXfer:auxv:read+");
>>               put_packet(s, buf);
>>               break;
>>           }
>> @@ -1173,6 +1174,46 @@ 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);
>> +        }
>> +#endif /* !CONFIG_USER_ONLY */
>>           /* Unrecognised 'q' command.  */
>>           goto unknown_command;
>>
diff mbox

Patch

diff --git a/gdbstub.c b/gdbstub.c
index d1b5afd..30f3bbc 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -1127,6 +1127,7 @@  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+");
              }
+            pstrcat(buf, sizeof(buf), ";qXfer:auxv:read+");
              put_packet(s, buf);
              break;
          }
@@ -1173,6 +1174,46 @@  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);
+        }
+#endif /* !CONFIG_USER_ONLY */
          /* Unrecognised 'q' command.  */
          goto unknown_command;