From: John Baldwin Date: Wed, 6 Jul 2022 22:39:14 +0000 (-0700) Subject: regcache: Add collect/supply_regset variants that accept a register base. X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=fa7e7c64625cf1d5b94ded94ad543e8576c0a7ab;p=thirdparty%2Fbinutils-gdb.git regcache: Add collect/supply_regset variants that accept a register base. Some register sets described by an array of regcache_map_entry structures do not have fixed register numbers in their associated architecture but do describe a block of registers whose numbers are at fixed offsets relative to some base register value. An example of this are the TLS register sets for the ARM and AArch64 architectures. Currently OS-specific architectures create register maps and register sets dynamically using the register base number. However, this requires duplicating the code to create the register map and register set. To reduce duplication, add variants of the collect_regset and supply_regset regcache methods which accept a base register number. For valid register map entries (i.e. not REGCACHE_MAP_SKIP), add this base register number to the value from the map entry to determine the final register number. --- diff --git a/gdb/regcache.c b/gdb/regcache.c index 0bd5a2a1632..627ba6569c9 100644 --- a/gdb/regcache.c +++ b/gdb/regcache.c @@ -1253,7 +1253,7 @@ regcache::transfer_regset_register (struct regcache *out_regcache, int regnum, /* See regcache.h. */ void -regcache::transfer_regset (const struct regset *regset, +regcache::transfer_regset (const struct regset *regset, int regbase, struct regcache *out_regcache, int regnum, const gdb_byte *in_buf, gdb_byte *out_buf, size_t size) const @@ -1268,6 +1268,9 @@ regcache::transfer_regset (const struct regset *regset, int regno = map->regno; int slot_size = map->size; + if (regno != REGCACHE_MAP_SKIP) + regno += regbase; + if (slot_size == 0 && regno != REGCACHE_MAP_SKIP) slot_size = m_descr->sizeof_register[regno]; @@ -1315,7 +1318,18 @@ void regcache::supply_regset (const struct regset *regset, int regnum, const void *buf, size_t size) { - transfer_regset (regset, this, regnum, (const gdb_byte *) buf, nullptr, size); + transfer_regset (regset, 0, this, regnum, (const gdb_byte *) buf, nullptr, + size); +} + +/* See regcache.h. */ + +void +regcache::supply_regset (const struct regset *regset, int regbase, + int regnum, const void *buf, size_t size) +{ + transfer_regset (regset, regbase, this, regnum, (const gdb_byte *) buf, + nullptr, size); } /* Collect register REGNUM from REGCACHE to BUF, using the register @@ -1334,11 +1348,19 @@ void regcache::collect_regset (const struct regset *regset, int regnum, void *buf, size_t size) const { - transfer_regset (regset, nullptr, regnum, nullptr, (gdb_byte *) buf, size); + transfer_regset (regset, 0, nullptr, regnum, nullptr, (gdb_byte *) buf, size); } /* See regcache.h */ +void +regcache::collect_regset (const struct regset *regset, int regbase, + int regnum, void *buf, size_t size) const +{ + transfer_regset (regset, regbase, nullptr, regnum, nullptr, (gdb_byte *) buf, + size); +} + bool regcache_map_supplies (const struct regcache_map_entry *map, int regnum, struct gdbarch *gdbarch, size_t size) diff --git a/gdb/regcache.h b/gdb/regcache.h index f905f511418..47c0409beec 100644 --- a/gdb/regcache.h +++ b/gdb/regcache.h @@ -150,6 +150,14 @@ extern void regcache_collect_regset (const struct regset *regset, int regnum, void *buf, size_t size); +extern void regcache_supply_regset (const struct regset *regset, int regbase, + struct regcache *regcache, + int regnum, const void *buf, + size_t size); +extern void regcache_collect_regset (const struct regset *regset, int regbase, + const struct regcache *regcache, + int regnum, void *buf, size_t size); + /* Return true if a set of registers contains the value of the register numbered REGNUM. The size of the set of registers is given in SIZE, and the layout of the set of registers is described @@ -390,9 +398,21 @@ public: void cooked_write_part (int regnum, int offset, int len, const gdb_byte *buf); - void supply_regset (const struct regset *regset, + /* Transfer a set of registers (as described by REGSET) between + REGCACHE and BUF. If REGNUM == -1, transfer all registers + belonging to the regset, otherwise just the register numbered + REGNUM. The REGSET's 'regmap' field must point to an array of + 'struct regcache_map_entry'. The valid register numbers in each + entry in 'struct regcache_map_entry' are offset by REGBASE. */ + + void supply_regset (const struct regset *regset, int regbase, int regnum, const void *buf, size_t size); + void collect_regset (const struct regset *regset, int regbase, int regnum, + void *buf, size_t size) const; + + void supply_regset (const struct regset *regset, + int regnum, const void *buf, size_t size); void collect_regset (const struct regset *regset, int regnum, void *buf, size_t size) const; @@ -434,7 +454,7 @@ private: /* Transfer a single or all registers belonging to a certain register set to or from a buffer. This is the main worker function for regcache_supply_regset and regcache_collect_regset. */ - void transfer_regset (const struct regset *regset, + void transfer_regset (const struct regset *regset, int regbase, struct regcache *out_regcache, int regnum, const gdb_byte *in_buf, gdb_byte *out_buf, size_t size) const;