aboutsummaryrefslogtreecommitdiff
path: root/gdbserver
diff options
context:
space:
mode:
authorLuis Machado <luis.machado@linaro.org>2021-01-12 15:53:00 -0300
committerLuis Machado <luis.machado@linaro.org>2021-03-17 10:40:01 -0300
commit610f24814ad15d53a8348e8399d393c05ca6d5b5 (patch)
tree86b57a01a2128a7a9b1da5208388209a00cab59b /gdbserver
parent4e3136f3dd60b870ca9c156dfc892dae77da236b (diff)
downloadgdb-610f24814ad15d53a8348e8399d393c05ca6d5b5.zip
gdb-610f24814ad15d53a8348e8399d393c05ca6d5b5.tar.gz
gdb-610f24814ad15d53a8348e8399d393c05ca6d5b5.tar.bz2
Enable capability writes to memory
Enable writing/forging capabilities to memory via the PTRACE_POKECAP ptrace request. This patch enables both GDB and gdbserver for Morello. For remote writes, we use the qXfer:capa:write packet. gdb/ChangeLog: 2021-03-17 Luis Machado <luis.machado@arm.com> * aarch64-linux-nat.c (aarch64_linux_nat_target) <write_capability>: New member function override. (aarch64_linux_nat_target::write_capability): New member function. (maint_print_cap_from_addr_cmd): Adjust printing format. (maint_set_capability_in_memory_cmd): New maintenance function. (add_show_debug_regs_command): Register new maintenance command. * nat/aarch64-cap-linux.c (aarch64_linux_write_capability): New function. * nat/aarch64-cap-linux.h (aarch64_linux_write_capability): New prototype. * remote.c (remote_target) <write_capability>: New member function override. Adjust enum documentation for PACKET_qXfer_capability. (remote_target::write_capability): New member function. (_initialize_remote): Adjust documentation for PACKET_qXfer_capability. * target-debug.h (target_debug_print_gdb_array_view_const_gdb_byte): New macro. * target-delegates.c: Regenerate. * target.c (target_write_capability): New function. * target.h (struct target_ops) <write_capability>: New virtual member function. (target_write_capability): New prototype. gdbserver/ChangeLog: 2021-03-17 Luis Machado <luis.machado@arm.com> * linux-aarch64-low.cc (aarch64_target::qxfer_capability): Handle capability writes. * server.cc (handle_qxfer_capability): Likewise.
Diffstat (limited to 'gdbserver')
-rw-r--r--gdbserver/ChangeLog6
-rw-r--r--gdbserver/linux-aarch64-low.cc27
-rw-r--r--gdbserver/server.cc19
3 files changed, 44 insertions, 8 deletions
diff --git a/gdbserver/ChangeLog b/gdbserver/ChangeLog
index 8ff0209..a56de0f 100644
--- a/gdbserver/ChangeLog
+++ b/gdbserver/ChangeLog
@@ -1,3 +1,9 @@
+2021-03-17 Luis Machado <luis.machado@arm.com>
+
+ * linux-aarch64-low.cc (aarch64_target::qxfer_capability): Handle
+ capability writes.
+ * server.cc (handle_qxfer_capability): Likewise.
+
2021-01-15 Luis Machado <luis.machado@arm.com>
* linux-aarch64-low.cc (aarch64_fill_cregset): New function.
diff --git a/gdbserver/linux-aarch64-low.cc b/gdbserver/linux-aarch64-low.cc
index 3919b12..d0eaff5 100644
--- a/gdbserver/linux-aarch64-low.cc
+++ b/gdbserver/linux-aarch64-low.cc
@@ -3268,14 +3268,31 @@ aarch64_target::qxfer_capability (const CORE_ADDR address,
struct user_cap cap;
- if (!aarch64_linux_read_capability (tid, address, cap))
+ if (readbuf != nullptr)
{
- warning (_("Unable to read capability from address."));
- return 0;
+ if (!aarch64_linux_read_capability (tid, address, cap))
+ {
+ warning (_("Unable to read capability from address."));
+ return 0;
+ }
+
+ /* Copy data to readbuf. */
+ memcpy (readbuf, &cap.tag, 1);
+ memcpy (readbuf + 1, &cap.val, 16);
}
+ else
+ {
+ /* Copy data from writebuf. */
+ memcpy (&cap.tag, writebuf, 1);
+ memcpy (&cap.val, writebuf + 1, 16);
+ memset (&cap.__reserved, 0, 15);
- memcpy (readbuf, &cap.tag, 1);
- memcpy (readbuf + 1, &cap.val, 16);
+ if (!aarch64_linux_write_capability (tid, address, cap))
+ {
+ warning (_("Unable to write capability to address."));
+ return 0;
+ }
+ }
return sizeof (cap.val) + 1;
}
diff --git a/gdbserver/server.cc b/gdbserver/server.cc
index c62dac5..c40eda5 100644
--- a/gdbserver/server.cc
+++ b/gdbserver/server.cc
@@ -1913,14 +1913,27 @@ handle_qxfer_capability (const char *annex, gdb_byte *readbuf,
const gdb_byte *writebuf, ULONGEST offset,
LONGEST len)
{
- if (!the_target->supports_qxfer_capability () || writebuf != NULL)
+ if (!the_target->supports_qxfer_capability ())
return -2;
+ gdb_assert (readbuf != nullptr || writebuf != nullptr);
+
CORE_ADDR addr;
unpack_varlen_hex (annex, &addr);
- /* Read a capability and its tag. */
- return the_target->qxfer_capability (addr, readbuf, NULL, offset, len);
+ if (readbuf != nullptr)
+ {
+ /* Read a capability and its tag. */
+ return the_target->qxfer_capability (addr, readbuf, nullptr, offset, len);
+ }
+ else
+ {
+ /* Write a capability to memory. */
+ return the_target->qxfer_capability (addr, nullptr, writebuf, offset,
+ len);
+ }
+
+ return -2;
}
static const struct qxfer qxfer_packets[] =