diff options
author | Luis Machado <luis.machado@linaro.org> | 2021-01-12 15:53:00 -0300 |
---|---|---|
committer | Luis Machado <luis.machado@linaro.org> | 2021-03-17 10:40:01 -0300 |
commit | 610f24814ad15d53a8348e8399d393c05ca6d5b5 (patch) | |
tree | 86b57a01a2128a7a9b1da5208388209a00cab59b /gdbserver | |
parent | 4e3136f3dd60b870ca9c156dfc892dae77da236b (diff) | |
download | gdb-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/ChangeLog | 6 | ||||
-rw-r--r-- | gdbserver/linux-aarch64-low.cc | 27 | ||||
-rw-r--r-- | gdbserver/server.cc | 19 |
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[] = |