This is the mail archive of the gdb-cvs@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[binutils-gdb] Look for FIR in the last FreeBSD/mips floating-point register.


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=7755ddb77d227d1d5c1b211e989fafb17e26765d

commit 7755ddb77d227d1d5c1b211e989fafb17e26765d
Author: John Baldwin <jhb@FreeBSD.org>
Date:   Tue Aug 29 15:04:09 2017 -0700

    Look for FIR in the last FreeBSD/mips floating-point register.
    
    FreeBSD/mips kernels were recently changed to include the floating
    point implementation revision register in the floating point register
    set exported in process cores and via ptrace() (r318067).  This change
    will first ship in FreeBSD 12.0 when it is eventually released.  The
    space used to hold FIR was previously reserved in 'struct fpreg' as a
    zero-filled dummy for padding, so 'struct fpreg' has not changed in
    size.  Since FIR should be non-zero on all MIPS processors supported
    by FreeBSD, ignore a value of 0 from 'struct fpreg' and only report
    non-zero values as a valid FIR register.
    
    gdb/ChangeLog:
    
    	* mips-fbsd-nat.c (getfpregs_supplies): Return true for FIR.
    	* mips-fbsd-tdep.c (mips_fbsd_supply_fpregs): Split supply of FSR
    	out of loop and add supply of FIR.
    	(mips_fbsd_collect_fpregs): Split collect of FSR out of loop and
    	add collect of FIR.

Diff:
---
 gdb/ChangeLog        |  8 ++++++++
 gdb/mips-fbsd-nat.c  |  2 +-
 gdb/mips-fbsd-tdep.c | 43 ++++++++++++++++++++++++++++++-------------
 3 files changed, 39 insertions(+), 14 deletions(-)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 926c966..5559bc2 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,11 @@
+2017-08-29  John Baldwin  <jhb@FreeBSD.org>
+
+	* mips-fbsd-nat.c (getfpregs_supplies): Return true for FIR.
+	* mips-fbsd-tdep.c (mips_fbsd_supply_fpregs): Split supply of FSR
+	out of loop and add supply of FIR.
+	(mips_fbsd_collect_fpregs): Split collect of FSR out of loop and
+	add collect of FIR.
+
 2017-08-28  Simon Marchi  <simon.marchi@ericsson.com>
 
 	PR gdb/21827
diff --git a/gdb/mips-fbsd-nat.c b/gdb/mips-fbsd-nat.c
index 53817d7..c381186 100644
--- a/gdb/mips-fbsd-nat.c
+++ b/gdb/mips-fbsd-nat.c
@@ -46,7 +46,7 @@ static bool
 getfpregs_supplies (struct gdbarch *gdbarch, int regnum)
 {
   return (regnum >= mips_regnum (gdbarch)->fp0
-	  && regnum < mips_regnum (gdbarch)->fp_implementation_revision);
+	  && regnum <= mips_regnum (gdbarch)->fp_implementation_revision);
 }
 
 /* Fetch register REGNUM from the inferior.  If REGNUM is -1, do this
diff --git a/gdb/mips-fbsd-tdep.c b/gdb/mips-fbsd-tdep.c
index 44b960d..feb18e1 100644
--- a/gdb/mips-fbsd-tdep.c
+++ b/gdb/mips-fbsd-tdep.c
@@ -39,7 +39,8 @@
 
 /* Number of registers in `struct fpreg' from <machine/reg.h>.  The
    first 32 hold floating point registers.  33 holds the FSR.  The
-   34th is a dummy for padding.  */
+   34th holds FIR on FreeBSD 12.0 and newer kernels.  On older kernels
+   it was a zero-filled dummy for padding.  */
 #define MIPS_FBSD_NUM_FPREGS	34
 
 /* Supply a single register.  The register size might not match, so use
@@ -72,14 +73,23 @@ mips_fbsd_supply_fpregs (struct regcache *regcache, int regnum,
 {
   struct gdbarch *gdbarch = get_regcache_arch (regcache);
   const gdb_byte *regs = (const gdb_byte *) fpregs;
-  int i, fp0num, fsrnum;
+  int i, fp0num;
 
   fp0num = mips_regnum (gdbarch)->fp0;
-  fsrnum = mips_regnum (gdbarch)->fp_control_status;
-  for (i = fp0num; i <= fsrnum; i++)
-    if (regnum == i || regnum == -1)
-      mips_fbsd_supply_reg (regcache, i,
-			    regs + (i - fp0num) * regsize, regsize);
+  for (i = 0; i <= 32; i++)
+    if (regnum == fp0num + i || regnum == -1)
+      mips_fbsd_supply_reg (regcache, fp0num + i,
+			    regs + i * regsize, regsize);
+  if (regnum == mips_regnum (gdbarch)->fp_control_status || regnum == -1)
+    mips_fbsd_supply_reg (regcache, mips_regnum (gdbarch)->fp_control_status,
+			  regs + 32 * regsize, regsize);
+  if ((regnum == mips_regnum (gdbarch)->fp_implementation_revision
+       || regnum == -1)
+      && extract_unsigned_integer (regs + 33 * regsize, regsize,
+				   gdbarch_byte_order (gdbarch)) != 0)
+    mips_fbsd_supply_reg (regcache,
+			  mips_regnum (gdbarch)->fp_implementation_revision,
+			  regs + 33 * regsize, regsize);
 }
 
 /* Supply the general-purpose registers stored in GREGS to REGCACHE.
@@ -109,14 +119,21 @@ mips_fbsd_collect_fpregs (const struct regcache *regcache, int regnum,
 {
   struct gdbarch *gdbarch = get_regcache_arch (regcache);
   gdb_byte *regs = (gdb_byte *) fpregs;
-  int i, fp0num, fsrnum;
+  int i, fp0num;
 
   fp0num = mips_regnum (gdbarch)->fp0;
-  fsrnum = mips_regnum (gdbarch)->fp_control_status;
-  for (i = fp0num; i <= fsrnum; i++)
-    if (regnum == i || regnum == -1)
-      mips_fbsd_collect_reg (regcache, i,
-			     regs + (i - fp0num) * regsize, regsize);
+  for (i = 0; i < 32; i++)
+    if (regnum == fp0num + i || regnum == -1)
+      mips_fbsd_collect_reg (regcache, fp0num + i,
+			     regs + i * regsize, regsize);
+  if (regnum == mips_regnum (gdbarch)->fp_control_status || regnum == -1)
+    mips_fbsd_collect_reg (regcache, mips_regnum (gdbarch)->fp_control_status,
+			   regs + 32 * regsize, regsize);
+  if (regnum == mips_regnum (gdbarch)->fp_implementation_revision
+      || regnum == -1)
+    mips_fbsd_collect_reg (regcache,
+			   mips_regnum (gdbarch)->fp_implementation_revision,
+			   regs + 33 * regsize, regsize);
 }
 
 /* Collect the general-purpose registers from REGCACHE and store them


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]