[2/3] gdb: xtensa-linux: add call0 support

Message ID 1484783438-13780-3-git-send-email-jcmvbkbc@gmail.com
State New, archived
Headers

Commit Message

Max Filippov Jan. 18, 2017, 11:50 p.m. UTC
  Correctly handle a0- registers. This allows debugging call0 code in
linux natively.
The register structure is the same for windowed and call0 ABIs because
currently linux kernel internally requires windowed registers, so they are
always present.

2017-01-18  Max Filippov  <jcmvbkbc@gmail.com>
gdb/
	* xtensa-linux-nat.c (C0_NREGS): New definition.
	(fill_gregset): Call regcache_raw_collect for a single specified
	register or for all registers in a0_base..a0_base + C0_NREGS
	range.
	(supply_gregset_reg): Call regcache_raw_supply for a single
	specified register or for all registers in a0_base..a0_base +
	C0_NREGS range.
---
 gdb/xtensa-linux-nat.c | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)
  

Comments

Luis Machado Feb. 13, 2017, 6:37 p.m. UTC | #1
On 01/18/2017 05:50 PM, Max Filippov wrote:
> Correctly handle a0- registers. This allows debugging call0 code in
> linux natively.
> The register structure is the same for windowed and call0 ABIs because
> currently linux kernel internally requires windowed registers, so they are
> always present.
>
> 2017-01-18  Max Filippov  <jcmvbkbc@gmail.com>
> gdb/

drop gdb/

I have no further comments on the patch.
  

Patch

diff --git a/gdb/xtensa-linux-nat.c b/gdb/xtensa-linux-nat.c
index afe15f6..2693939 100644
--- a/gdb/xtensa-linux-nat.c
+++ b/gdb/xtensa-linux-nat.c
@@ -45,6 +45,8 @@ 
    hardware-specific overlays.  */
 #include "xtensa-xtregs.c"
 
+#define C0_NREGS   16	/* Number of A-registers to track.  */
+
 void
 fill_gregset (const struct regcache *regcache,
 	      gdb_gregset_t *gregsetp, int regnum)
@@ -94,6 +96,20 @@  fill_gregset (const struct regcache *regcache,
 			      gdbarch_tdep (gdbarch)->ar_base + i,
 			      &regs->ar[i]);
     }
+  if (regnum >= gdbarch_tdep (gdbarch)->a0_base
+      && regnum < gdbarch_tdep (gdbarch)->a0_base + C0_NREGS)
+    regcache_raw_collect (regcache, regnum,
+			  &regs->ar[(4 * regs->windowbase + regnum
+				     - gdbarch_tdep (gdbarch)->a0_base)
+			  % gdbarch_tdep (gdbarch)->num_aregs]);
+  else if (regnum == -1)
+    {
+      for (i = 0; i < C0_NREGS; ++i)
+	regcache_raw_collect (regcache,
+			      gdbarch_tdep (gdbarch)->a0_base + i,
+			      &regs->ar[(4 * regs->windowbase + i)
+			      % gdbarch_tdep (gdbarch)->num_aregs]);
+    }
 }
 
 static void
@@ -146,6 +162,20 @@  supply_gregset_reg (struct regcache *regcache,
 			      gdbarch_tdep (gdbarch)->ar_base + i,
 			      &regs->ar[i]);
     }
+  if (regnum >= gdbarch_tdep (gdbarch)->a0_base
+      && regnum < gdbarch_tdep (gdbarch)->a0_base + C0_NREGS)
+    regcache_raw_supply (regcache, regnum,
+			 &regs->ar[(4 * regs->windowbase + regnum
+				    - gdbarch_tdep (gdbarch)->a0_base)
+			 % gdbarch_tdep (gdbarch)->num_aregs]);
+  else if (regnum == -1)
+    {
+      for (i = 0; i < C0_NREGS; ++i)
+	regcache_raw_supply (regcache,
+			     gdbarch_tdep (gdbarch)->a0_base + i,
+			     &regs->ar[(4 * regs->windowbase + i)
+			     % gdbarch_tdep (gdbarch)->num_aregs]);
+    }
 }
 
 void