[1/5] Add regcache_map_supplies helper routine.

Message ID 20210528202614.2081-2-jhb@FreeBSD.org
State New
Headers show
Series
  • Add helper functions for FreeBSD native targets
Related show

Commit Message

John Baldwin May 28, 2021, 8:26 p.m.
This helper can be used in the fetch_registers and store_registers
target methods to determine if a register set includes a specific
register.

gdb/ChangeLog:

	* regcache.c (regcache_map_supplies): New.
	* regcache.h: Likewise.
---
 gdb/ChangeLog  |  5 +++++
 gdb/regcache.c | 27 +++++++++++++++++++++++++++
 gdb/regcache.h |  7 +++++++
 3 files changed, 39 insertions(+)

-- 
2.31.1

Comments

Pedro Alves July 10, 2021, 7:25 p.m. | #1
On 2021-05-28 9:26 p.m., John Baldwin wrote:

> diff --git a/gdb/regcache.h b/gdb/regcache.h

> index ee254f381f4..a1f63d40253 100644

> --- a/gdb/regcache.h

> +++ b/gdb/regcache.h

> @@ -150,6 +150,13 @@ extern void regcache_collect_regset (const struct regset *regset,

>  				     int regnum, void *buf, size_t size);

>  

>  

> +/* Return true if a set of registers (whose layout is described by

> +   MAP) contains the value of the register numbered REGNUM.  */


I assume SIZE is the register's size?  From the description of regcache_map, some of the
map entries have sizes smaller than the corresponding register's size.  How do
they interact?  IOW, please document SIZE.  :-)

> +

> +extern bool regcache_map_supplies (const struct regcache_map_entry *map,

> +				   int regnum, struct gdbarch *gdbarch,

> +				   size_t size);
John Baldwin July 12, 2021, 1:13 p.m. | #2
On 7/10/21 12:25 PM, Pedro Alves wrote:
> On 2021-05-28 9:26 p.m., John Baldwin wrote:

> 

>> diff --git a/gdb/regcache.h b/gdb/regcache.h

>> index ee254f381f4..a1f63d40253 100644

>> --- a/gdb/regcache.h

>> +++ b/gdb/regcache.h

>> @@ -150,6 +150,13 @@ extern void regcache_collect_regset (const struct regset *regset,

>>   				     int regnum, void *buf, size_t size);

>>   

>>   

>> +/* Return true if a set of registers (whose layout is described by

>> +   MAP) contains the value of the register numbered REGNUM.  */

> 

> I assume SIZE is the register's size?  From the description of regcache_map, some of the

> map entries have sizes smaller than the corresponding register's size.  How do

> they interact?  IOW, please document SIZE.  :-)


Ah, will do.  In this case SIZE is the size of the entire register set, the same as
the size passed to regcache::collect_regset and regcache::supply_regset that this
is intended to be paired with, e.g. for a native target fetch_registers:

   struct reg regs;

   if (regnum == -1
      || regcache_map_supplies (map, regnum, gdbarch, sizeof (regs))
     {
       /* populate 'regs' */

       regcache->supply_regset (regset, regnum, &regs, sizeof (regs));
     }

I've modified the comment to:

/* 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
    by MAP.  */

-- 
John Baldwin
Pedro Alves July 12, 2021, 1:21 p.m. | #3
On 2021-07-12 2:13 p.m., John Baldwin wrote:
> On 7/10/21 12:25 PM, Pedro Alves wrote:

>> On 2021-05-28 9:26 p.m., John Baldwin wrote:

>>

>>> diff --git a/gdb/regcache.h b/gdb/regcache.h

>>> index ee254f381f4..a1f63d40253 100644

>>> --- a/gdb/regcache.h

>>> +++ b/gdb/regcache.h

>>> @@ -150,6 +150,13 @@ extern void regcache_collect_regset (const struct regset *regset,

>>>                        int regnum, void *buf, size_t size);

>>>     +/* Return true if a set of registers (whose layout is described by

>>> +   MAP) contains the value of the register numbered REGNUM.  */

>>

>> I assume SIZE is the register's size?  From the description of regcache_map, some of the

>> map entries have sizes smaller than the corresponding register's size.  How do

>> they interact?  IOW, please document SIZE.  :-)

> 

> Ah, will do.  In this case SIZE is the size of the entire register set, the same as

> the size passed to regcache::collect_regset and regcache::supply_regset that this

> is intended to be paired with, e.g. for a native target fetch_registers:

> 

>   struct reg regs;

> 

>   if (regnum == -1

>      || regcache_map_supplies (map, regnum, gdbarch, sizeof (regs))

>     {

>       /* populate 'regs' */

> 

>       regcache->supply_regset (regset, regnum, &regs, sizeof (regs));

>     }

> 

> I've modified the comment to:

> 

> /* 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

>    by MAP.  */

> 


Works for me, thanks!

Patch

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 03910c0634c..2e61aead178 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,8 @@ 
+2021-05-28  John Baldwin <jhb@FreeBSD.org>
+
+	* regcache.c (regcache_map_supplies): New.
+	* regcache.h: Likewise.
+
 2021-05-27  Simon Marchi  <simon.marchi@polymtl.ca>
 
 	* Fix tab after space indentation issues throughout.
diff --git a/gdb/regcache.c b/gdb/regcache.c
index fde0c612975..fe61512e50d 100644
--- a/gdb/regcache.c
+++ b/gdb/regcache.c
@@ -1264,6 +1264,33 @@  regcache::collect_regset (const struct regset *regset,
   transfer_regset (regset, nullptr, regnum, nullptr, (gdb_byte *) buf, size);
 }
 
+/* See regcache.h  */
+
+bool
+regcache_map_supplies (const struct regcache_map_entry *map, int regnum,
+		       struct gdbarch *gdbarch, size_t size)
+{
+  int offs = 0, count;
+
+  for (; (count = map->count) != 0; map++)
+    {
+      int regno = map->regno;
+      int slot_size = map->size;
+
+      if (slot_size == 0 && regno != REGCACHE_MAP_SKIP)
+	slot_size = register_size (gdbarch, regno);
+
+      if (regno != REGCACHE_MAP_SKIP && regnum >= regno
+	  && regnum < regno + count)
+	return offs + (regnum - regno + 1) * slot_size <= size;
+
+      offs += count * slot_size;
+      if (offs >= size)
+	return false;
+    }
+  return false;
+}
+
 /* See gdbsupport/common-regcache.h.  */
 
 bool
diff --git a/gdb/regcache.h b/gdb/regcache.h
index ee254f381f4..a1f63d40253 100644
--- a/gdb/regcache.h
+++ b/gdb/regcache.h
@@ -150,6 +150,13 @@  extern void regcache_collect_regset (const struct regset *regset,
 				     int regnum, void *buf, size_t size);
 
 
+/* Return true if a set of registers (whose layout is described by
+   MAP) contains the value of the register numbered REGNUM.  */
+
+extern bool regcache_map_supplies (const struct regcache_map_entry *map,
+				   int regnum, struct gdbarch *gdbarch,
+				   size_t size);
+
 /* The type of a register.  This function is slightly more efficient
    then its gdbarch vector counterpart since it returns a precomputed
    value stored in a table.  */