From 5a680bf9f2c89df9d192a1f5c6b02022babf7793 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Tue, 13 Jul 2021 08:16:12 -0700 Subject: [PATCH] fbsd-nat: Add helper functions to fetch and store register sets. In particular, this supports register sets described by a regcache_map which are fetched and stored with dedicated ptrace operations. These functions are intended to be used in architecture-specific fetch_registers and store_registers target methods. --- gdb/fbsd-nat.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ gdb/fbsd-nat.h | 43 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+) diff --git a/gdb/fbsd-nat.c b/gdb/fbsd-nat.c index 234e74fcfd4..33eddb5f22c 100644 --- a/gdb/fbsd-nat.c +++ b/gdb/fbsd-nat.c @@ -1601,6 +1601,52 @@ fbsd_nat_target::supports_disable_randomization () #endif } +/* See fbsd-nat.h. */ + +void +fbsd_nat_target::fetch_register_set (struct regcache *regcache, int regnum, + int fetch_op, const struct regset *regset, + void *regs, size_t size) +{ + const struct regcache_map_entry *map + = (const struct regcache_map_entry *) regset->regmap; + pid_t pid = get_ptrace_pid (regcache->ptid ()); + + if (regnum == -1 || regcache_map_supplies (map, regnum, regcache->arch(), + size)) + { + if (ptrace (fetch_op, pid, (PTRACE_TYPE_ARG3) regs, 0) == -1) + perror_with_name (_("Couldn't get registers")); + + regcache->supply_regset (regset, regnum, regs, size); + } +} + +/* See fbsd-nat.h. */ + +void +fbsd_nat_target::store_register_set (struct regcache *regcache, int regnum, + int fetch_op, int store_op, + const struct regset *regset, void *regs, + size_t size) +{ + const struct regcache_map_entry *map + = (const struct regcache_map_entry *) regset->regmap; + pid_t pid = get_ptrace_pid (regcache->ptid ()); + + if (regnum == -1 || regcache_map_supplies (map, regnum, regcache->arch(), + size)) + { + if (ptrace (fetch_op, pid, (PTRACE_TYPE_ARG3) regs, 0) == -1) + perror_with_name (_("Couldn't get registers")); + + regcache->collect_regset (regset, regnum, regs, size); + + if (ptrace (store_op, pid, (PTRACE_TYPE_ARG3) regs, 0) == -1) + perror_with_name (_("Couldn't write registers")); + } +} + void _initialize_fbsd_nat (); void _initialize_fbsd_nat () diff --git a/gdb/fbsd-nat.h b/gdb/fbsd-nat.h index 1fdb939935c..a59065415be 100644 --- a/gdb/fbsd-nat.h +++ b/gdb/fbsd-nat.h @@ -21,6 +21,8 @@ #define FBSD_NAT_H #include "inf-ptrace.h" +#include "regcache.h" +#include "regset.h" #include #include @@ -103,6 +105,47 @@ public: bool supports_multi_process () override; bool supports_disable_randomization () override; + +private: + /* Helper routines for use in fetch_registers and store_registers in + subclasses. These routines fetch and store a single set of + registers described by REGSET. The REGSET's 'regmap' field must + point to an array of 'struct regcache_map_entry'. + + FETCH_OP is a ptrace operation to fetch the set of registers from + a native thread. STORE_OP is a ptrace operation to store the set + of registers to a native thread. + + The caller must provide storage for the set of registers in REGS, + and SIZE is the size of the storage. */ + + void fetch_register_set (struct regcache *regcache, int regnum, int fetch_op, + const struct regset *regset, void *regs, size_t size); + + void store_register_set (struct regcache *regcache, int regnum, int fetch_op, + int store_op, const struct regset *regset, + void *regs, size_t size); +protected: + /* Wrapper versions of the above helpers which accept a register set + type such as 'struct reg' or 'struct fpreg'. */ + + template + void fetch_register_set (struct regcache *regcache, int regnum, int fetch_op, + const struct regset *regset) + { + Regset regs; + fetch_register_set (regcache, regnum, fetch_op, regset, ®s, + sizeof (regs)); + } + + template + void store_register_set (struct regcache *regcache, int regnum, int fetch_op, + int store_op, const struct regset *regset) + { + Regset regs; + store_register_set (regcache, regnum, fetch_op, store_op, regset, ®s, + sizeof (regs)); + } }; #endif /* fbsd-nat.h */ -- 2.30.2