|
@@ -2172,6 +2172,12 @@ static void handle_query_supported(GdbCmdContext *gdb_ctx, void *user_ctx)
|
|
";ReverseStep+;ReverseContinue+");
|
|
";ReverseStep+;ReverseContinue+");
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+#ifdef CONFIG_USER_ONLY
|
|
|
|
+ if (gdbserver_state.c_cpu->opaque) {
|
|
|
|
+ g_string_append(gdbserver_state.str_buf, ";qXfer:auxv:read+");
|
|
|
|
+ }
|
|
|
|
+#endif
|
|
|
|
+
|
|
if (gdb_ctx->num_params &&
|
|
if (gdb_ctx->num_params &&
|
|
strstr(gdb_ctx->params[0].data, "multiprocess+")) {
|
|
strstr(gdb_ctx->params[0].data, "multiprocess+")) {
|
|
gdbserver_state.multiprocess = true;
|
|
gdbserver_state.multiprocess = true;
|
|
@@ -2233,6 +2239,46 @@ static void handle_query_xfer_features(GdbCmdContext *gdb_ctx, void *user_ctx)
|
|
gdbserver_state.str_buf->len, true);
|
|
gdbserver_state.str_buf->len, true);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+#if defined(CONFIG_USER_ONLY) && defined(CONFIG_LINUX_USER)
|
|
|
|
+static void handle_query_xfer_auxv(GdbCmdContext *gdb_ctx, void *user_ctx)
|
|
|
|
+{
|
|
|
|
+ TaskState *ts;
|
|
|
|
+ unsigned long offset, len, saved_auxv, auxv_len;
|
|
|
|
+ const char *mem;
|
|
|
|
+
|
|
|
|
+ if (gdb_ctx->num_params < 2) {
|
|
|
|
+ put_packet("E22");
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ offset = gdb_ctx->params[0].val_ul;
|
|
|
|
+ len = gdb_ctx->params[1].val_ul;
|
|
|
|
+ ts = gdbserver_state.c_cpu->opaque;
|
|
|
|
+ saved_auxv = ts->info->saved_auxv;
|
|
|
|
+ auxv_len = ts->info->auxv_len;
|
|
|
|
+ mem = (const char *)(saved_auxv + offset);
|
|
|
|
+ if (offset > auxv_len) {
|
|
|
|
+ put_packet("E00");
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (len > (MAX_PACKET_LENGTH - 5) / 2) {
|
|
|
|
+ len = (MAX_PACKET_LENGTH - 5) / 2;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (len < auxv_len - offset) {
|
|
|
|
+ g_string_assign(gdbserver_state.str_buf, "m");
|
|
|
|
+ memtox(gdbserver_state.str_buf, mem, len);
|
|
|
|
+ } else {
|
|
|
|
+ g_string_assign(gdbserver_state.str_buf, "l");
|
|
|
|
+ memtox(gdbserver_state.str_buf, mem, auxv_len - offset);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ put_packet_binary(gdbserver_state.str_buf->str,
|
|
|
|
+ gdbserver_state.str_buf->len, true);
|
|
|
|
+}
|
|
|
|
+#endif
|
|
|
|
+
|
|
static void handle_query_attached(GdbCmdContext *gdb_ctx, void *user_ctx)
|
|
static void handle_query_attached(GdbCmdContext *gdb_ctx, void *user_ctx)
|
|
{
|
|
{
|
|
put_packet(GDB_ATTACHED);
|
|
put_packet(GDB_ATTACHED);
|
|
@@ -2338,6 +2384,14 @@ static GdbCmdParseEntry gdb_gen_query_table[] = {
|
|
.cmd_startswith = 1,
|
|
.cmd_startswith = 1,
|
|
.schema = "s:l,l0"
|
|
.schema = "s:l,l0"
|
|
},
|
|
},
|
|
|
|
+#if defined(CONFIG_USER_ONLY) && defined(CONFIG_LINUX_USER)
|
|
|
|
+ {
|
|
|
|
+ .handler = handle_query_xfer_auxv,
|
|
|
|
+ .cmd = "Xfer:auxv:read::",
|
|
|
|
+ .cmd_startswith = 1,
|
|
|
|
+ .schema = "l,l0"
|
|
|
|
+ },
|
|
|
|
+#endif
|
|
{
|
|
{
|
|
.handler = handle_query_attached,
|
|
.handler = handle_query_attached,
|
|
.cmd = "Attached:",
|
|
.cmd = "Attached:",
|