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] MIPS/gdbserver: Fix issues with $zero register reads


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

commit e4439e4346ec0d2cb0e65b497d26382e1054c93b
Author: Maciej W. Rozycki <macro@mips.com>
Date:   Tue May 22 00:55:08 2018 +0100

    MIPS/gdbserver: Fix issues with $zero register reads
    
    Consistently supply hardwired $zero as a zeroed register, correcting
    issues with the PTRACE_GETREGS path that currently copies the value of
    $restart into $zero as illustrated by this program:
    
    $ cat read.c
    
    int
    main (void)
    {
      char buf[1024];
      ssize_t size;
    
      size = read (0, buf, sizeof (buf));
    
      return size;
    }
    $
    
    and this corresponding debug session:
    
    (gdb) break main
    Breakpoint 1 at 0x120000970: file read.c, line 9.
    (gdb) target remote :2346
    Remote debugging using :2346
    Reading symbols from .../sysroot/mips-r2-hard/lib64/ld.so.1...done.
    0x000000fff7fca5a0 in __start ()
       from .../sysroot/mips-r2-hard/lib64/ld.so.1
    (gdb) continue
    Continuing.
    
    Breakpoint 1, main () at read.c:9
    9	  size = read (0, buf, sizeof (buf));
    (gdb) info registers
                      zero               at               v0               v1
     R0   0000000000000000 0000000000000001 000000fff7ffe710 0000000000000000
                        a0               a1               a2               a3
     R4   0000000000000001 000000ffffffeb88 000000ffffffeb98 0000000000000000
                        a4               a5               a6               a7
     R8   000000fff7fc8800 000000fff7fc38f0 000000ffffffeb80 2f2f2f2f2f2f2f2f
                        t0               t1               t2               t3
     R12  0000000000000437 0000000000000002 000000fff7ffd000 0000000120000a00
                        s0               s1               s2               s3
     R16  000000fff7fc7068 0000000120000b90 0000000000000000 0000000000000000
                        s4               s5               s6               s7
     R20  0000000000521d88 0000000000522608 0000000000000000 0000000000000000
                        t8               t9               k0               k1
     R24  0000000000000000 0000000120000970 0000000000000000 0000000000000000
                        gp               sp               s8               ra
     R28  000000fff7fc8800 000000ffffffea50 0000000000000000 000000fff7e4088c
                    status               lo               hi         badvaddr
          0000000000109cf3 0000000000005ea5 0000000000000211 000000fff7eadf00
                     cause               pc
          0000000000800024 0000000120000970
                      fcsr              fir          restart
                  00000000         00f30000 0000000000000000
    (gdb) continue
    Continuing.
    ^C
    
    Program received signal SIGINT, Interrupt.
    0x000000fff7f084ac in __GI___libc_read (fd=0, buf=0xffffffe640, nbytes=1024)
        at ../sysdeps/unix/sysv/linux/read.c:27
    27	  return SYSCALL_CANCEL (read, fd, buf, nbytes);
    (gdb) info registers
                      zero               at               v0               v1
     R0   0000000000001388 0000000000000001 0000000000000200 000000fff7ffe710
                        a0               a1               a2               a3
     R4   0000000000000000 000000ffffffe640 0000000000000400 0000000000000001
                        a4               a5               a6               a7
     R8   000000fff7fc8800 000000fff7fc38f0 000000ffffffeb80 2f2f2f2f2f2f2f2f
                        t0               t1               t2               t3
     R12  00000000000005e3 0000000000000002 000000fff7ffd000 000000012000099c
                        s0               s1               s2               s3
     R16  000000fff7fc7068 0000000120000b90 0000000000000000 0000000000000000
                        s4               s5               s6               s7
     R20  0000000000521d88 0000000000522608 0000000000000000 0000000000000000
                        t8               t9               k0               k1
     R24  0000000000000000 000000fff7f2da20 0000000000000000 0000000000000000
                        gp               sp               s8               ra
     R28  000000fff7fc8800 000000ffffffe600 0000000000000000 000000012000099c
                    status               lo               hi         badvaddr
          0000000000109cf3 00000000000001e6 00000000000000be 000000fff7f08470
                     cause               pc
          0000000000800020 000000fff7f084ac
                      fcsr              fir          restart
                  00000000         00f30000 0000000000001388
    (gdb)
    
    and with the PTRACE_PEEKUSR path that does not supply this register at
    all, causing issues analogous to ones addressed for the native MIPS
    backend with commit 4e6ff0e1b86f ("MIPS/Linux/native: Supply $zero for
    the !PTRACE_GETREGS case"):
    
    (gdb) info registers
                      zero               at               v0               v1
     R0      <unavailable> 0000000000000001 0000000000000001 0000000000000000
                        a0               a1               a2               a3
     R4   00000001200212b0 0000000000000000 0000000000000021 000000012001a260
                        a4               a5               a6               a7
     R8   000000012001a260 0000000000000004 800000010cab1680 fffffffffffffff8
                        t0               t1               t2               t3
     R12  0000000000000000 000000fff7edab68 0000000000000001 0000000000000000
                        s0               s1               s2               s3
     R16  000000fff7ee2068 0000000120008b80 0000000000000000 0000000000000000
                        s4               s5               s6               s7
     R20  000000000052e5c8 000000000052f008 0000000000000000 0000000000000000
                        t8               t9               k0               k1
     R24  0000000000000000 00000001200027c0 0000000000000000 0000000000000000
                        gp               sp               s8               ra
     R28  00000001200212b0 000000ffffffc880 000000ffffffc880 0000000120005ee8
                    status               lo               hi         badvaddr
             <unavailable> 0000000000943efe 000000000000000e 000000012001a008
                     cause               pc
          0000000000800024 0000000120005ee8
                      fcsr              fir          restart
                  0e800000         00f30000 0000000000000000
    (gdb)
    
    and (under certain circumstances):
    
    (gdb) next
    Register 0 is not available
    (gdb)
    
    The problem with PTRACE_GETREGS happens because `mips_store_gregset'
    supplies the contents of register slot #0, occupied by $restart, to
    $zero.  The problem with PTRACE_PEEKUSR happens because for $zero
    `mips_cannot_fetch_register' returns one, and no alternative way to
    supply that register has been defined.
    
    Correct `mips_store_gregset' then for the PTRACE_GETREGS case and add
    `mips_fetch_register' for the PTRACE_PEEKUSR case.
    
    	gdb/gdbserver/
    	* linux-mips-low.c (mips_fetch_register): New function.  Update
    	preceding comment.
    	(mips_store_gregset): Supply 0 rather than $restart for $zero.
    	(the_low_target): Wire `mips_fetch_register'.

Diff:
---
 gdb/gdbserver/ChangeLog        |  7 +++++++
 gdb/gdbserver/linux-mips-low.c | 24 ++++++++++++++++++++----
 2 files changed, 27 insertions(+), 4 deletions(-)

diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog
index 5e7ea10..3c55457 100644
--- a/gdb/gdbserver/ChangeLog
+++ b/gdb/gdbserver/ChangeLog
@@ -1,3 +1,10 @@
+2018-05-21  Maciej W. Rozycki  <macro@mips.com>
+
+	* linux-mips-low.c (mips_fetch_register): New function.  Update
+	preceding comment.
+	(mips_store_gregset): Supply 0 rather than $restart for $zero.
+	(the_low_target): Wire `mips_fetch_register'.
+
 2018-05-10  Joel Brobecker  <brobecker@adacore.com>
 
 	* lynx-i386-low.c (LYNXOS_178): New macro.
diff --git a/gdb/gdbserver/linux-mips-low.c b/gdb/gdbserver/linux-mips-low.c
index d423633..ff87dd7 100644
--- a/gdb/gdbserver/linux-mips-low.c
+++ b/gdb/gdbserver/linux-mips-low.c
@@ -198,8 +198,8 @@ struct arch_lwp_info
 
 /* Pseudo registers can not be read.  ptrace does not provide a way to
    read (or set) PS_REGNUM, and there's no point in reading or setting
-   ZERO_REGNUM.  We also can not set BADVADDR, CAUSE, or FCRIR via
-   ptrace().  */
+   ZERO_REGNUM, it's always 0.  We also can not set BADVADDR, CAUSE,
+   or FCRIR via ptrace().  */
 
 static int
 mips_cannot_fetch_register (int regno)
@@ -242,6 +242,20 @@ mips_cannot_store_register (int regno)
   return 0;
 }
 
+static int
+mips_fetch_register (struct regcache *regcache, int regno)
+{
+  const struct target_desc *tdesc = current_process ()->tdesc;
+
+  if (find_regno (tdesc, "r0") == regno)
+    {
+      supply_register_zeroed (regcache, regno);
+      return 1;
+    }
+
+  return 0;
+}
+
 static CORE_ADDR
 mips_get_pc (struct regcache *regcache)
 {
@@ -750,7 +764,9 @@ mips_store_gregset (struct regcache *regcache, const void *buf)
 
   use_64bit = (register_size (regcache->tdesc, 0) == 8);
 
-  for (i = 0; i < 32; i++)
+  supply_register_by_name_zeroed (regcache, "r0");
+
+  for (i = 1; i < 32; i++)
     mips_supply_register (regcache, use_64bit, i, regset + i);
 
   mips_supply_register (regcache, use_64bit,
@@ -879,7 +895,7 @@ struct linux_target_ops the_low_target = {
   mips_regs_info,
   mips_cannot_fetch_register,
   mips_cannot_store_register,
-  NULL, /* fetch_register */
+  mips_fetch_register,
   mips_get_pc,
   mips_set_pc,
   NULL, /* breakpoint_kind_from_pc */


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