aboutsummaryrefslogtreecommitdiff
path: root/gdb/gdbserver
diff options
context:
space:
mode:
authorAlan Hayward <alan.hayward@arm.com>2018-05-11 11:52:56 +0100
committerSimon Marchi <simon.marchi@ericsson.com>2018-06-01 10:40:20 -0400
commite884af534b7e77ba214e8bd8d7ba8fb6009231a4 (patch)
tree9da28d4411ef18d194c40cad6130f8bdb0380399 /gdb/gdbserver
parentd56bdeb9c2e434b91d5e6d605b92bb1cd21177e5 (diff)
downloadbinutils-users/simark/regcache-for-alan.zip
binutils-users/simark/regcache-for-alan.tar.gz
binutils-users/simark/regcache-for-alan.tar.bz2
Ptrace support for Aarch64 SVEusers/simark/regcache-for-alan
Add support for reading and writing registers for Aarch64 SVE. I've made this functionality common as it will be required for gdbserver when gdbsever sve support is added. Given that gdbserver does not yet call this function, I am happy to remove the regcache commonise functions from the previous patch. However, this would result in code in nat/ that does not compile for gdbserver. I wanted to avoid that. We need to support the cases where the kernel only gives us a fpsimd structure. This occurs when there is no active SVE state in the kernel (for example, after starting a new process). As per the covering email description, I've included large chunks of linux kernel headers within an ifdef. Formatting of these macros remains identical to the Kernel versions (ie not adapted to GNU style). Added checks to make sure the vector length has not changed whilst the process is running. 2018-05-11 Alan Hayward <alan.hayward@arm.com> gdb/ * aarch64-linux-nat.c (fetch_sveregs_from_thread): New function. (store_sveregs_to_thread): Likewise. (aarch64_linux_fetch_inferior_registers): Check for SVE. (aarch64_linux_store_inferior_registers): Likewise. * nat/aarch64-sve-linux-ptrace.c (aarch64_sve_get_sveregs): New function. (aarch64_sve_regs_copy_to_regcache): Likewise. (aarch64_sve_regs_copy_from_regcache): Likewise. * nat/aarch64-sve-linux-ptrace.h (aarch64_sve_get_sveregs): New declaration. (aarch64_sve_regs_copy_to_regcache): Likewise. (aarch64_sve_regs_copy_from_regcache): Likewise. (sve_context): Structure from Linux headers. (SVE_SIG_ZREGS_SIZE): Define from Linux headers. (SVE_SIG_ZREG_SIZE): Likewise. (SVE_SIG_PREG_SIZE): Likewise. (SVE_SIG_FFR_SIZE): Likewise. (SVE_SIG_REGS_OFFSET): Likewise. (SVE_SIG_ZREGS_OFFSET): Likewise. (SVE_SIG_ZREG_OFFSET): Likewise. (SVE_SIG_ZREGS_SIZE): Likewise. (SVE_SIG_PREGS_OFFSET): Likewise. (SVE_SIG_PREG_OFFSET): Likewise. (SVE_SIG_PREGS_SIZE): Likewise. (SVE_SIG_FFR_OFFSET): Likewise. (SVE_SIG_REGS_SIZE): Likewise. (SVE_SIG_CONTEXT_SIZE): Likewise. (SVE_PT_REGS_MASK): Likewise. (SVE_PT_REGS_FPSIMD): Likewise. (SVE_PT_REGS_SVE): Likewise. (SVE_PT_VL_INHERIT): Likewise. (SVE_PT_VL_ONEXEC): Likewise. (SVE_PT_REGS_OFFSET): Likewise. (SVE_PT_FPSIMD_OFFSET): Likewise. (SVE_PT_FPSIMD_SIZE): Likewise. (SVE_PT_SVE_ZREG_SIZE): Likewise. (SVE_PT_SVE_PREG_SIZE): Likewise. (SVE_PT_SVE_FFR_SIZE): Likewise. (SVE_PT_SVE_FPSR_SIZE): Likewise. (SVE_PT_SVE_FPCR_SIZE): Likewise. (__SVE_SIG_TO_PT): Likewise. (SVE_PT_SVE_OFFSET): Likewise. (SVE_PT_SVE_ZREGS_OFFSET): Likewise. (SVE_PT_SVE_ZREG_OFFSET): Likewise. (SVE_PT_SVE_ZREGS_SIZE): Likewise. (SVE_PT_SVE_PREGS_OFFSET): Likewise. (SVE_PT_SVE_PREG_OFFSET): Likewise. (SVE_PT_SVE_PREGS_SIZE): Likewise. (SVE_PT_SVE_FFR_OFFSET): Likewise. (SVE_PT_SVE_FPSR_OFFSET): Likewise. (SVE_PT_SVE_FPCR_OFFSET): Likewise. (SVE_PT_SVE_SIZE): Likewise. (SVE_PT_SIZE): Likewise. (HAS_SVE_STATE): New define. gdbserver * Makefile.in: Add aarch64-sve-linux-ptrace.c.
Diffstat (limited to 'gdb/gdbserver')
-rw-r--r--gdb/gdbserver/Makefile.in1
-rw-r--r--gdb/gdbserver/regcache.c8
-rw-r--r--gdb/gdbserver/regcache.h20
3 files changed, 15 insertions, 14 deletions
diff --git a/gdb/gdbserver/Makefile.in b/gdb/gdbserver/Makefile.in
index 675faa4..f924e6a 100644
--- a/gdb/gdbserver/Makefile.in
+++ b/gdb/gdbserver/Makefile.in
@@ -219,6 +219,7 @@ SFILES = \
$(srcdir)/common/tdesc.c \
$(srcdir)/common/vec.c \
$(srcdir)/common/xml-utils.c \
+ $(srcdir)/nat/aarch64-sve-linux-ptrace.c \
$(srcdir)/nat/linux-btrace.c \
$(srcdir)/nat/linux-namespaces.c \
$(srcdir)/nat/linux-osdata.c \
diff --git a/gdb/gdbserver/regcache.c b/gdb/gdbserver/regcache.c
index 88f0db0..39bc6f0 100644
--- a/gdb/gdbserver/regcache.c
+++ b/gdb/gdbserver/regcache.c
@@ -159,7 +159,7 @@ init_register_cache (struct regcache *regcache,
struct regcache *
new_register_cache (const struct target_desc *tdesc)
{
- struct regcache *regcache = XCNEW (struct regcache);
+ struct regcache *regcache = new struct regcache;
gdb_assert (tdesc->registers_size != 0);
@@ -174,7 +174,7 @@ free_register_cache (struct regcache *regcache)
if (regcache->registers_owned)
free (regcache->registers);
free (regcache->register_status);
- free (regcache);
+ delete regcache;
}
}
@@ -506,10 +506,10 @@ regcache::get_register_status (int regnum) const
first OFFSET bytes) to the contents of BUF (without any offset). Returns 0
if identical. */
-int
+bool
regcache::raw_compare (int regnum, const void *buf, int offset) const
{
gdb_assert (register_size (tdesc, regnum) > offset);
return memcmp (buf, register_data (this, regnum, 1) + offset,
- register_size (tdesc, regnum) - offset);
+ register_size (tdesc, regnum) - offset) == 0;
}
diff --git a/gdb/gdbserver/regcache.h b/gdb/gdbserver/regcache.h
index b3631be..ad199a9 100644
--- a/gdb/gdbserver/regcache.h
+++ b/gdb/gdbserver/regcache.h
@@ -28,31 +28,31 @@ struct target_desc;
inferior; this is primarily for simplicity, as the performance
benefit is minimal. */
-struct regcache
+struct regcache : public reg_buffer_common
{
/* The regcache's target description. */
- const struct target_desc *tdesc;
+ const struct target_desc *tdesc = nullptr;
/* Whether the REGISTERS buffer's contents are valid. If false, we
haven't fetched the registers from the target yet. Not that this
register cache is _not_ pass-through, unlike GDB's. Note that
"valid" here is unrelated to whether the registers are available
in a traceframe. For that, check REGISTER_STATUS below. */
- int registers_valid;
- int registers_owned;
- unsigned char *registers;
+ int registers_valid = 0;
+ int registers_owned = 0;
+ unsigned char *registers = nullptr;
#ifndef IN_PROCESS_AGENT
/* One of REG_UNAVAILBLE or REG_VALID. */
- unsigned char *register_status;
+ unsigned char *register_status = nullptr;
#endif
- void raw_supply (int regnum, const void *buf);
+ void raw_supply (int regnum, const void *buf) override;
- void raw_collect (int regnum, void *buf) const;
+ void raw_collect (int regnum, void *buf) const override;
- int raw_compare (int regnum, const void *buf, int offset) const;
+ bool raw_compare (int regnum, const void *buf, int offset) const override;
- enum register_status get_register_status (int regnum) const;
+ enum register_status get_register_status (int regnum) const override;
};
struct regcache *init_register_cache (struct regcache *regcache,