Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Aditya Vidyadhar Kamath <akamath996@gmail.com>
To: ulrich.weigand@de.ibm.com, simon.marchi@polymtl.ca, tom@tromey.com
Cc: gdb-patches@sourceware.org, Aditya.Kamath1@ibm.com,
	sangamesh.swamy@in.ibm.com,
	Aditya Vidyadhar Kamath <aditya.kamath1@ibm.com>
Subject: [PATCH v5 4/4] Fix 32-bit GPR and SPR register reads/writes in pthdb callbacks.
Date: Tue, 13 Oct 2026 16:49:21 +0530	[thread overview]
Message-ID: <20261013111917.68981-8-akamath996@gmail.com> (raw)
In-Reply-To: <20261013111917.68981-2-akamath996@gmail.com>

From: Aditya Vidyadhar Kamath <aditya.kamath1@ibm.com>

pdc_read_regs reads GPRs into a uint32_t[32] local array when the
thread is 32-bit, then copies it into pthdb_context_t::gpr which is
uint64_t[32].  The memcpy treated the uint32_t[] data as if it were
already uint64_t, so each 32-bit value was silently widened with
whatever happened to be adjacent in memory.  Replace the memcpy with
an element-wise assignment so each value is correctly zero-extended.

pdc_read_regs also reads the 32-bit SPR set into a struct ptsprs and
copies it with memcpy into &context->msr.  The field order in struct
ptsprs is iar, msr, cr, lr, ctr, xer, mq, while pthdb_context_t
has msr, iar, lr, ctr, cr, xer, fpscr, fpscrx, mq.  The memcpy
therefore wrote every SPR into the wrong context field and corrupted
the fields that follow msr.  Replace the memcpy with explicit
field-by-field assignments.

pdc_write_regs has the symmetric bugs for the write direction.  Add
the arch64 branch that was missing for GPRs and SPRs:

  64-bit: pass context->gpr / &context->msr directly.
  32-bit GPRs: truncate each context->gpr[i] (uint64_t) into a local
    uint32_t gprs32[] array, then call ptrace64aix.
  32-bit SPRs: pre-fetch the current struct ptsprs to preserve any
    reserved fields, fill in the named fields from the context, then
    call ptrace64aix.

Also reword the "untested" comment in both pdc_read_regs and
pdc_write_regs.  The callbacks do not appear to be invoked during
normal debugging, but they must be registered: without them the OS
refuses to initialise the pthdb session and several thread-debug
functions fail.

Note: pt_mq in struct ptsprs is the legacy Multiply/Quotient register
from the original POWER architecture.  It is present in the struct on
all supported AIX releases and is included for completeness.
---
 gdb/aix-thread.c | 69 ++++++++++++++++++++++++++++++++++++++----------
 1 file changed, 55 insertions(+), 14 deletions(-)

diff --git a/gdb/aix-thread.c b/gdb/aix-thread.c
index 795948424b2..f732f5167ff 100644
--- a/gdb/aix-thread.c
+++ b/gdb/aix-thread.c
@@ -411,11 +411,10 @@ pdc_read_regs (pthdb_user_t user_current_pid,
 	       unsigned long long flags,
 	       pthdb_context_t *context)
 {
-  /* This function doesn't appear to be used, so we could probably
-   just return 0 here.  HOWEVER, if it is not defined, the OS will
-   complain and several thread debug functions will fail.  In case
-   this is needed, I have implemented what I think it should do,
-   however this code is untested.  */
+  /* This function does not appear to be called during normal debugging,
+     but it must be registered: if the callback is absent the OS refuses
+     to initialise the pthdb session and several thread-debug functions
+     fail.  */
 
   uint64_t gprs64[ppc_num_gprs];
   uint32_t gprs32[ppc_num_gprs];
@@ -443,7 +442,8 @@ pdc_read_regs (pthdb_user_t user_current_pid,
 	{
 	  if (!ptrace64aix (PTT_READ_GPRS, tid, (long long) gprs32, 0, NULL))
 	    memset (gprs32, 0, sizeof (gprs32));
-	  memcpy (context->gpr, gprs32, sizeof (gprs32));
+	  for (int i = 0; i < ppc_num_gprs; i++)
+	    context->gpr[i] = gprs32[i];
 	}
     }
 
@@ -468,7 +468,15 @@ pdc_read_regs (pthdb_user_t user_current_pid,
 	{
 	  if (!ptrace64aix (PTT_READ_SPRS, tid, (long long) &sprs32, 0, NULL))
 	    memset (&sprs32, 0, sizeof (sprs32));
-	  memcpy (&context->msr, &sprs32, sizeof (sprs32));
+	  context->iar = sprs32.pt_iar;
+	  context->msr = sprs32.pt_msr;
+	  context->cr = sprs32.pt_cr;
+	  context->lr = sprs32.pt_lr;
+	  context->ctr = sprs32.pt_ctr;
+	  context->xer = sprs32.pt_xer;
+	  context->fpscr = sprs32.pt_fpscr;
+	  context->fpscrx = sprs32.pt_fpscrx;
+	  context->mq = sprs32.pt_mq;
 	}
     }
 
@@ -502,11 +510,13 @@ pdc_write_regs (pthdb_user_t user_current_pid,
 		unsigned long long flags,
 		pthdb_context_t *context)
 {
-  /* This function doesn't appear to be used, so we could probably
-     just return 0 here.  HOWEVER, if it is not defined, the OS will
-     complain and several thread debug functions will fail.  In case
-     this is needed, I have implemented what I think it should do,
-     however this code is untested.  */
+  /* This function does not appear to be called during normal debugging,
+     but it must be registered: if the callback is absent the OS refuses
+     to initialise the pthdb session and several thread-debug functions
+     fail.  */
+
+  struct aix_thread_variables *data;
+  data = get_thread_data_helper_for_pid (user_current_pid);
 
   if (debug_aix_thread)
     gdb_printf (gdb_stdlog, "pdc_write_regs tid=%d flags=%s\n",
@@ -514,7 +524,17 @@ pdc_write_regs (pthdb_user_t user_current_pid,
 
   /* General-purpose registers.  */
   if (flags & PTHDB_FLAG_GPRS)
-    ptrace64aix (PTT_WRITE_GPRS, tid, (long long) context->gpr, 0, NULL);
+    {
+      if (data->arch64)
+	ptrace64aix (PTT_WRITE_GPRS, tid, (long long) context->gpr, 0, NULL);
+      else
+	{
+	  uint32_t gprs32[ppc_num_gprs];
+	  for (int i = 0; i < ppc_num_gprs; i++)
+	    gprs32[i] = context->gpr[i];
+	  ptrace64aix (PTT_WRITE_GPRS, tid, (long long) gprs32, 0, NULL);
+	}
+    }
 
   /* Floating-point registers.  */
   if (flags & PTHDB_FLAG_FPRS)
@@ -522,7 +542,28 @@ pdc_write_regs (pthdb_user_t user_current_pid,
 
   /* Special-purpose registers.  */
   if (flags & PTHDB_FLAG_SPRS)
-    ptrace64aix (PTT_WRITE_SPRS, tid, (long long) &context->msr, 0, NULL);
+    {
+      if (data->arch64)
+	ptrace64aix (PTT_WRITE_SPRS, tid, (long long) &context->msr, 0, NULL);
+      else
+	{
+	  struct ptsprs sprs32;
+
+	  /* Pre-fetch so the reserved fields are preserved.  */
+	  if (!ptrace64aix (PTT_READ_SPRS, tid, (long long) &sprs32, 0, NULL))
+	    memset (&sprs32, 0, sizeof (sprs32));
+	  sprs32.pt_iar = context->iar;
+	  sprs32.pt_msr = context->msr;
+	  sprs32.pt_cr = context->cr;
+	  sprs32.pt_lr = context->lr;
+	  sprs32.pt_ctr = context->ctr;
+	  sprs32.pt_xer = context->xer;
+	  sprs32.pt_fpscr = context->fpscr;
+	  sprs32.pt_fpscrx = context->fpscrx;
+	  sprs32.pt_mq = context->mq;	/* MQ is legacy; present in ptsprs.  */
+	  ptrace64aix (PTT_WRITE_SPRS, tid, (long long) &sprs32, 0, NULL);
+	}
+    }
 
   /* vector registers.  */
   if (__power_vmx () && (flags & PTHDB_FLAG_REGS))
-- 
2.51.2


  parent reply	other threads:[~2026-10-13 11:21 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-13 11:19 [PATCH v5 1/4] Remove stale legacy code from rs6000-aix-nat.c file Aditya Vidyadhar Kamath
2026-10-13 11:19 ` [PATCH v5 2/4] Remove obsolete getthrds and HAVE_PTRACE64 configure checks Aditya Vidyadhar Kamath
2026-10-13 11:19 ` [PATCH v5 3/4] Modernise aix-thread.c by combining ptrace wrappers Aditya Vidyadhar Kamath
2026-10-13 11:19 ` Aditya Vidyadhar Kamath [this message]
2026-10-13 12:00 ` [PATCH v5 1/4] Remove stale legacy code from rs6000-aix-nat.c file Ulrich Weigand
2026-10-13 12:55   ` Aditya Kamath
2026-10-13 13:31     ` Ulrich Weigand
2026-10-13 17:16       ` Simon Marchi
2026-10-14  9:15         ` Aditya Kamath
2026-10-14 10:44           ` Ulrich Weigand
2026-10-15 13:38             ` Aditya Kamath
2026-10-15 14:37               ` Ulrich Weigand

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20261013111917.68981-8-akamath996@gmail.com \
    --to=akamath996@gmail.com \
    --cc=Aditya.Kamath1@ibm.com \
    --cc=gdb-patches@sourceware.org \
    --cc=sangamesh.swamy@in.ibm.com \
    --cc=simon.marchi@polymtl.ca \
    --cc=tom@tromey.com \
    --cc=ulrich.weigand@de.ibm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox