[PATCH v2 11/11] gdbserver: fix the declared type of register_status in regcache

Tankut Baris Aktemur
2024-12-30T10:58:59Z

The register_status field of regcache is declared as `unsigned char *`.
This is incorrect, because `enum register_status` from
gdbsupport/common-regcache.h is based on signed char and
REG_UNAVAILABLE is defined as -1. Fix the declared type.

Now that we are modifying the declaration, also use a unique_ptr
and make the field private.

The get/set methods already use the correct type, but we update cast
operations in two places.
---
gdbserver/regcache.cc | 22 +++++++++++-----------
gdbserver/regcache.h | 11 ++++++++---
2 files changed, 19 insertions(+), 14 deletions(-)

diff --git a/gdbserver/regcache.cc b/gdbserver/regcache.cc
index 562524306dfb36c8be88be5056b2fdddb6ca0b3c..54826e886143349923877deaf8b5c7f556eddfc0 100644
--- a/gdbserver/regcache.cc
+++ b/gdbserver/regcache.cc
@@ -120,7 +120,7 @@ regcache::regcache (const target_desc *tdesc,
this->registers = regbuf;
this->registers_owned = false;
#ifndef IN_PROCESS_AGENT
- this->register_status = nullptr;
+ m_register_status = nullptr;
#endif
this->registers_fetched = false;
}
@@ -139,8 +139,8 @@ regcache::regcache (const target_desc *tdesc)
this->registers
= (unsigned char *) xmalloc (tdesc->registers_size);
this->registers_owned = true;
- this->register_status
- = (unsigned char *) xmalloc (tdesc->reg_defs.size ());
+ size_t num_regs = tdesc->reg_defs.size ();
+ m_register_status.reset (new enum register_status[num_regs]);
reset (REG_UNKNOWN);
}

@@ -148,7 +148,6 @@ regcache::~regcache ()
{
if (registers_owned)
free (registers);
- free (register_status);
}

#endif
@@ -161,7 +160,8 @@ regcache::reset (enum register_status status)
of garbage. */
memset (this->registers, 0, this->tdesc->registers_size);
#ifndef IN_PROCESS_AGENT
- memset (this->register_status, status, this->tdesc->reg_defs.size ());
+ for (int i = 0; i < this->tdesc->reg_defs.size (); i++)
+ set_register_status (i, status);
#endif
}

@@ -174,8 +174,8 @@ regcache::copy_from (regcache *src)

memcpy (this->registers, src->registers, src->tdesc->registers_size);
#ifndef IN_PROCESS_AGENT
- if (this->register_status != nullptr && src->register_status != nullptr)
- memcpy (this->register_status, src->register_status,
+ if (m_register_status != nullptr && src->m_register_status != nullptr)
+ memcpy (m_register_status.get (), src->m_register_status.get (),
src->tdesc->reg_defs.size ());
#endif
this->registers_fetched = src->registers_fetched;
@@ -486,8 +486,8 @@ regcache::get_register_status (int regnum) const
{
#ifndef IN_PROCESS_AGENT
gdb_assert (regnum >= 0 && regnum < tdesc->reg_defs.size ());
- if (register_status != nullptr)
- return (enum register_status) (register_status[regnum]);
+ if (m_register_status != nullptr)
+ return m_register_status[regnum];
else
return REG_VALID;
#else
@@ -500,8 +500,8 @@ regcache::set_register_status (int regnum, enum register_status status)
{
#ifndef IN_PROCESS_AGENT
gdb_assert (regnum >= 0 && regnum < tdesc->reg_defs.size ());
- if (register_status != nullptr)
- register_status[regnum] = status;
+ if (m_register_status != nullptr)
+ m_register_status[regnum] = status;
#endif
}

diff --git a/gdbserver/regcache.h b/gdbserver/regcache.h
index b5a0b85982515dd545c6f79688ba7a4fd177b3d6..6828611550e71ffea8af5fec4f4a073b8644da67 100644
--- a/gdbserver/regcache.h
+++ b/gdbserver/regcache.h
@@ -20,6 +20,7 @@
#define GDBSERVER_REGCACHE_H

#include "gdbsupport/common-regcache.h"
+#include <memory>

struct thread_info;
struct target_desc;
@@ -43,9 +44,6 @@ struct regcache : public reg_buffer_common
bool registers_owned = false;
unsigned char *registers = nullptr;
#ifndef IN_PROCESS_AGENT
- /* See gdbsupport/common-regcache.h. */
- unsigned char *register_status = nullptr;
-
/* Constructors. */
regcache (const target_desc *tdesc);

@@ -80,6 +78,13 @@ struct regcache : public reg_buffer_common

/* Copy the contents of SRC into this regcache. */
void copy_from (regcache *src);
+
+private:
+
+#ifndef IN_PROCESS_AGENT
+ /* See gdbsupport/common-regcache.h. */
+ std::unique_ptr<enum register_status[]> m_register_status;
+#endif
};

regcache *get_thread_regcache (thread_info *thread, bool fetch = true);

--
2.34.1

Intel Deutschland GmbH
Registered Address: Am Campeon 10, 85579 Neubiberg, Germany
Tel: +49 89 99 8853-0, www.intel.de
Managing Directors: Sean Fennelly, Jeffrey Schneiderman, Tiffany Doon Silva