[21/26] gdbserver: use REG_UNKNOWN for a regcache's register statuses

Message ID 1fcffbf8ffd62b07585baebff38b66f10ec0a112.1677582745.git.tankut.baris.aktemur@intel.com
State New
Headers
Series gdbserver: refactor regcache and allow gradually populating |

Commit Message

Tankut Baris Aktemur Feb. 28, 2023, 11:28 a.m. UTC
  When a regcache is initialized, the values of registers are not
fetched yet.  Thus, initialize the register statuses to REG_UNKNOWN
instead of REG_UNAVAILABLE, because the latter rather means "we
attempted to fetch but could not obtain the value".

The definitions of the reg status enums (from
gdbsupport/common-regcache.h) as a reminder:

    /* The register value is not in the cache, and we don't know yet
       whether it's available in the target (or traceframe).  */
    REG_UNKNOWN = 0,

    /* The register value is valid and cached.  */
    REG_VALID = 1,

    /* The register value is unavailable.  E.g., we're inspecting a
       traceframe, and this register wasn't collected.  Note that this
       "unavailable" is different from saying the register does not
       exist in the target's architecture --- in that case, the target
       should have given us a target description that does not include
       the register in the first place.  */
    REG_UNAVAILABLE = -1

Similarly, when the regcache is invalidated, change all the statuses
back to REG_UNKNOWN.
---
 gdbserver/regcache.cc | 16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)
  

Patch

diff --git a/gdbserver/regcache.cc b/gdbserver/regcache.cc
index 09ea58bdbd6..2befb30e337 100644
--- a/gdbserver/regcache.cc
+++ b/gdbserver/regcache.cc
@@ -64,9 +64,17 @@  regcache::fetch ()
       switch_to_thread (this->thread);
 
       /* Invalidate all registers, to prevent stale left-overs.  */
-      memset (register_status, REG_UNAVAILABLE, tdesc->reg_defs.size ());
+      discard ();
       fetch_inferior_registers (this, -1);
       registers_fetched = true;
+
+      /* Make sure that the registers that could not be fetched are
+	 now unavailable.  */
+      for (int i = 0; i < tdesc->reg_defs.size (); ++i)
+	{
+	  if (register_status[i] == REG_UNKNOWN)
+	    set_register_status (i, REG_UNAVAILABLE);
+	}
     }
 }
 
@@ -128,6 +136,9 @@  regcache_invalidate (void)
 void
 regcache::discard ()
 {
+#ifndef IN_PROCESS_AGENT
+  memset ((void *) register_status, REG_UNKNOWN, tdesc->reg_defs.size ());
+#endif
   registers_fetched = false;
 }
 
@@ -148,8 +159,7 @@  regcache::initialize (const target_desc *tdesc,
       this->registers_owned = true;
       this->register_status
 	= (enum register_status *) xmalloc (tdesc->reg_defs.size ());
-      memset ((void *) this->register_status, REG_UNAVAILABLE,
-	      tdesc->reg_defs.size ());
+      discard ();
 #else
       gdb_assert_not_reached ("can't allocate memory from the heap");
 #endif