summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Baldwin <jhb@FreeBSD.org>2022-08-10 12:14:16 -0700
committerJohn Baldwin <jhb@FreeBSD.org>2022-09-01 16:47:42 -0700
commit36d1b3bff14b48cb2166e0bc27cf74c9c3bc3c25 (patch)
tree1898cd45c0d8be4e705c450373e0f938b0a94232
parentcabfc6253d9d61d97cd3c6b0c4cae949dd36187b (diff)
downloadbinutils-gdb-36d1b3bff14b48cb2166e0bc27cf74c9c3bc3c25.tar.gz
Write memory capabilities atomically.
Use target_write_capability to write a capability atomically in put_frame_register.
-rw-r--r--gdb/frame.c14
1 files changed, 10 insertions, 4 deletions
diff --git a/gdb/frame.c b/gdb/frame.c
index 44b3bd09463..bc3189e3dac 100644
--- a/gdb/frame.c
+++ b/gdb/frame.c
@@ -1399,15 +1399,21 @@ put_frame_register (struct frame_info *frame, int regnum,
{
case lval_memory:
{
- write_memory (addr, buf, register_size (gdbarch, regnum));
-
/* If this value is a capability, we need to handle the capability tag
- as well. */
+ as an atomic write. */
if ((val_type->code () == TYPE_CODE_CAPABILITY
|| (val_type->code () == TYPE_CODE_PTR
&& TYPE_CAPABILITY (val_type)))
&& value_tagged (fromval))
- gdbarch_set_cap_tag_from_address (gdbarch, addr, value_tag (fromval));
+ {
+ gdb::byte_vector cap (register_size (gdbarch, regnum) + 1);
+
+ cap[0] = value_tag (fromval) ? 1 : 0;
+ memcpy (cap.data () + 1, buf, register_size (gdbarch, regnum));
+ if (target_write_capability (addr, cap))
+ break;
+ }
+ write_memory (addr, buf, register_size (gdbarch, regnum));
break;
}
case lval_register: