Bug 22286 - [MIPS] internal-error when read dspctl register
Summary: [MIPS] internal-error when read dspctl register
Status: RESOLVED FIXED
Alias: None
Product: gdb
Classification: Unclassified
Component: gdb (show other bugs)
Version: HEAD
: P2 normal
Target Milestone: 8.2
Assignee: Maciej W. Rozycki
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2017-10-12 11:06 UTC by Paul Hua
Modified: 2018-05-16 19:49 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Last reconfirmed: 2017-10-12 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Paul Hua 2017-10-12 11:06:16 UTC
I use 'info r' to read registers on mips64 target with dsp.

something wrong.

internal-error: void inf_ptrace_fetch_register(regcache*, int): Assertion `(size % sizeof (PTRACE_TYPE_RET)) == 0' failed.

----------------cut-------------------------------
(gdb) b main
Breakpoint 1 at 0x1200038b4
(gdb) r
Starting program: /usr/bin/ls 
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".

Breakpoint 1, 0x00000001200038b4 in main ()
(gdb) info r
                  zero               at               v0               v1
 R0   0000000000000000 0000000000000001 0000000000000000 000000fff7ffcf80 
                    a0               a1               a2               a3
 R4   0000000000000001 000000ffffffad98 000000ffffffada8 0000000000000000 
                    a4               a5               a6               a7
 R8   000000fff7f36820 000000fff7fdba18 000000ffffffad90 0000000000000001 
                    t0               t1               t2               t3
 R12  000000fff7d75140 000000000000000b 00000000f63d4e2e 000000fff7ffde28 
                    s0               s1               s2               s3
 R16  000000fff7f34cc8 000000012001d5e0 0000000000000000 0000000000000000 
                    s4               s5               s6               s7
 R20  000000012016d750 000000012015af48 0000000000000000 0000000000000000 
                    t8               t9               k0               k1
 R24  0000000000000000 00000001200038a0 0000000000000000 0000000000000000 
                    gp               sp               s8               ra
 R28  00000001200438a0 000000ffffffa900 0000000000000000 000000fff7d931a0 
                status               lo               hi         badvaddr
      ffffffff8500c8f3 0000000000000000 000000000000000a 000000fff7daefe8 
                 cause               pc
      0000000010000024 00000001200038b4 
                  fcsr              fir              hi1              lo1
              00000000         00770501 0000000000000000 0000000000000000 
                   hi2              lo2              hi3              lo3
      0000000000000000 0000000000000000 0000000000000000 0000000000000000 
                dspctl          restart
      
../../binutils-gdb_git_trunk/gdb/inf-ptrace.c:735: internal-error: void inf_ptrace_fetch_register(regcache*, int): Assertion `(size % sizeof (PTRACE_TYPE_RET)) == 0' failed.
A problem internal to GDB has been detected,
further debugging may prove unreliable.
Quit this debugging session? (y or n) 
--------------------------------------------------------------------------
Comment 1 Paul Hua 2017-10-12 11:32:28 UTC
In mips64-dsp-linux.c:102

102   tdesc_create_reg (feature, "dspctl", 78, 1, NULL, 32, "int");

define the reg size is '32'。

but in inf-ptrace.c:
734   size = register_size (gdbarch, regnum);
735   gdb_assert ((size % sizeof (PTRACE_TYPE_RET)) == 0);

the PTRACE_TYPE_RET is long, sizeof (PTRACE_TYPE_RET) is 8, size is 4, so triger the gdb_assert.

we should define dspctl size is 64, like status/cause register.

Changelog:

2017-10-12  Chenghua Xu  <paul.hua.gm@gmail.com>

        * mips64-dsp-linux.c (initialize_tdesc_mips64_dsp_linux): Change
          dspctl from 32 to 64 bit.


-----------------------------------------------------------------------

diff --git a/gdb/features/mips64-dsp-linux.c b/gdb/features/mips64-dsp-linux.c
index 05317b7..b42a8ce 100644
--- a/gdb/features/mips64-dsp-linux.c
+++ b/gdb/features/mips64-dsp-linux.c
@@ -99,7 +99,7 @@ initialize_tdesc_mips64_dsp_linux (void)
   tdesc_create_reg (feature, "lo2", 75, 1, NULL, 64, "int");
   tdesc_create_reg (feature, "hi3", 76, 1, NULL, 64, "int");
   tdesc_create_reg (feature, "lo3", 77, 1, NULL, 64, "int");
-  tdesc_create_reg (feature, "dspctl", 78, 1, NULL, 32, "int");
+  tdesc_create_reg (feature, "dspctl", 78, 1, NULL, 64, "int");

   feature = tdesc_create_feature (result, "org.gnu.gdb.mips.linux");
   tdesc_create_reg (feature, "restart", 79, 1, "system", 64, "int");
Comment 2 Paul Hua 2017-10-12 11:41:33 UTC
CC: macro@linux-mips.org, cause git blame to you.
Comment 3 Maciej W. Rozycki 2017-10-12 14:33:56 UTC
Hi Paul,

Thank you for your bug report and the proposed fix.

However the DSPControl register is architecturally 32-bit even on 64-bit
hardware, like CP1 control registers (e.g. FCSR, etc.) and unlike CP0
registers in general.  So I'd rather fix the problem the other way round.
I'll look into it.

NB I agree Status and Cause are inconsistent in that they are exposed as
64-bit while they are not.  The reason is historical and boils down to
the layout of the `g'/`G' RSP packets matching debug stubs which predate
the introduction of XML register descriptions.  This could be fixed in
a way similar to how I adjusted the handling of FCSR and FIR not so long
ago, however as a non-fatal issue this is not urgent.

Maciej
Comment 4 Maciej W. Rozycki 2018-05-16 17:20:50 UTC
Fix now posted: <https://patchwork.sourceware.org/patch/27300/>.

NB as observed in the submission n64 support for the DSP state
remains broken until <https://patchwork.kernel.org/patch/10402159/>
has been applied to the Linux kernel and n32 support will remain
broken due to a `ptrace' API limitation until both the kernel and GDB
have adopted the regset API for DSP state access.
Comment 5 Sourceware Commits 2018-05-16 19:45:27 UTC
The master branch has been updated by Maciej W. Rozycki <macro@sourceware.org>:

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

commit 1d7611244c140a1a08f3365cd5881120eba7749d
Author: Maciej W. Rozycki <macro@mips.com>
Date:   Wed May 16 20:43:30 2018 +0100

    PR gdb/22286: linux-nat-trad: Support arbitrary register widths
    
    Update `fetch_register' and `store_register' code to support arbitrary
    register widths rather than only ones that are a multiply of the size of
    the `ptrace' data type used with PTRACE_PEEKUSR and PTRACE_POKEUSR
    requests to access registers.  Remove associated assertions, correcting
    an issue with accessing the DSPControl (`$dspctl') register on n64 MIPS
    native targets:
    
    (gdb) print /x $dspctl
    .../gdb/linux-nat-trad.c:50: internal-error: void linux_nat_trad_target::fetch_register(regcache*, int): Assertion `(size % sizeof (PTRACE_TYPE_RET)) == 0' failed.
    A problem internal to GDB has been detected,
    further debugging may prove unreliable.
    Quit this debugging session? (y or n) n
    
    This is a bug, please report it.  For instructions, see:
    <http://www.gnu.org/software/gdb/bugs/>.
    
    .../gdb/linux-nat-trad.c:50: internal-error: void linux_nat_trad_target::fetch_register(regcache*, int): Assertion `(size % sizeof (PTRACE_TYPE_RET)) == 0' failed.
    A problem internal to GDB has been detected,
    further debugging may prove unreliable.
    Create a core file of GDB? (y or n) n
    Command aborted.
    (gdb)
    
    All registers are now reported correctly and their architectural
    hardware widths respected:
    
    (gdb) print /x $dspctl
    $1 = 0x55aa33cc
    (gdb) info registers
                      zero               at               v0               v1
     R0   0000000000000000 0000000000000001 000000fff7ffeb20 0000000000000000
                        a0               a1               a2               a3
     R4   0000000000000001 000000ffffffeaf8 000000ffffffeb08 0000000000000000
                        a4               a5               a6               a7
     R8   000000fff7ee3800 000000fff7ede8f0 000000ffffffeaf0 2f2f2f2f2f2f2f2f
                        t0               t1               t2               t3
     R12  0000000000000437 0000000000000002 000000fff7ffd000 0000000120000ad0
                        s0               s1               s2               s3
     R16  000000fff7ee2068 0000000120000e60 0000000000000000 0000000000000000
                        s4               s5               s6               s7
     R20  0000000000521ec8 0000000000522608 0000000000000000 0000000000000000
                        t8               t9               k0               k1
     R24  0000000000000000 0000000120000d9c 0000000000000000 0000000000000000
                        gp               sp               s8               ra
     R28  0000000120019030 000000ffffffe990 000000ffffffe990 000000fff7d5b88c
                    status               lo               hi         badvaddr
          0000000000109cf3 0000000000005ea5 0000000000000211 000000fff7fc6fe0
                     cause               pc
          0000000000800024 0000000120000dbc
                      fcsr              fir              hi1              lo1
                  00000000         00f30000 0000000000000000 0101010101010101
                       hi2              lo2              hi3              lo3
          0202020202020202 0303030303030303 0404040404040404 0505050505050505
                    dspctl          restart
                  55aa33cc 0000000000000000
    (gdb)
    
    NB due to the lack of access to 64-bit DSP hardware all DSP register
    values in the dumps are artificial and have been created with a debug
    change applied to the kernel handler of the `ptrace' syscall.
    
    The use of `store_unsigned_integer' and `extract_unsigned_integer'
    unconditionally in all cases rather than when actual data occupies a
    part of the data quantity exchanged with `ptrace' makes code perhaps
    marginally slower, however I think avoiding it is not worth code
    obfuscation it would cause.  If this turns out unfounded, then there
    should be no problem with optimizing this code later.
    
    	gdb/
    	PR gdb/22286
    	* linux-nat-trad.c (linux_nat_trad_target::fetch_register):
    	Also handle registers whose width is not a multiple of
    	PTRACE_TYPE_RET.
    	(linux_nat_trad_target::store_register): Likewise.
Comment 6 Maciej W. Rozycki 2018-05-16 19:49:29 UTC
Fix now committed, closing bug.