To reproduce: 1. Run the following command to start debuggee and stop at entry point: gdb /bin/true -ex 'b *0' -ex r -ex 'd 1' 2. Issue "p $fpscr", see the output "$1 = <unavailable>" (the bug) 3. Issue "p $s0", see output "$2 = 0" 4. Now you can finally get FPSCR via "p $fpscr", having "$3 = 0" as output 5. Step one instruction using "si" command 6. Issue "p $fpscr" to see <unavailable> again Tested on Raspberry Pi 1 Model B under Raspbian GNU/Linux 8. /proc/cpuinfo says: model name : ARMv6-compatible processor rev 7 (v6l) BogoMIPS : 697.95 Features : half thumb fastmult vfp edsp java tls CPU implementer : 0x41 CPU architecture: 7 CPU variant : 0x0 CPU part : 0xb76 CPU revision : 7 Hardware : BCM2835 Revision : 000e Serial : 000000009c40fec4
(In reply to Ruslan from comment #0) > To reproduce: > > 1. Run the following command to start debuggee and stop at entry point: > gdb /bin/true -ex 'b *0' -ex r -ex 'd 1' Could you show me the gdb output here? I wonder why /bin/true 's entry is on address 0x0.
(In reply to Yao Qi from comment #1) > Could you show me the gdb output here? I wonder why /bin/true 's entry is > on address 0x0. It's not on address zero. It's just a hack to make GDB stop on the first instruction available to the inferior process — otherwise, if you don't have debug symbols, you'll not be able to stop at the beginning of execution — be it _start or main (to my knowledge, this is the easiest way to achieve this). Here's how the session begins: $ gdb -q /bin/true -ex 'b *0' -ex r -ex 'd 1' -ex 'info reg $pc' Reading symbols from /bin/true...(no debugging symbols found)...done. Breakpoint 1 at 0x0 Starting program: /bin/true Warning: Cannot insert breakpoint 1. Cannot access memory at address 0x0 pc 0xb6fcfca0 0xb6fcfca0 <_start>
(In reply to Ruslan from comment #2) > > Here's how the session begins: > > $ gdb -q /bin/true -ex 'b *0' -ex r -ex 'd 1' -ex 'info reg $pc' > Reading symbols from /bin/true...(no debugging symbols found)...done. > Breakpoint 1 at 0x0 > Starting program: /bin/true > Warning: > Cannot insert breakpoint 1. > Cannot access memory at address 0x0 > > pc 0xb6fcfca0 0xb6fcfca0 <_start> I still can't reproduce it on armv7l panda board, gdb -q /bin/true -ex 'b *0' -ex r -ex 'd 1' Reading symbols from /bin/true...(no debugging symbols found)...done. Breakpoint 1 at 0x0 Starting program: /bin/true Warning: Cannot insert breakpoint 1. Cannot access memory at address 0x0 (gdb) p $fpscr $1 = 0 My board is armv7l, having vfp and vfpv3, but your board only has vfp. I don't have armv6l hardware. Can you build GDB from source and debug it yourself? You can debug GDB by setting breakpoint on arm_linux_fetch_inferior_registers and fetch_vfp_regs, and run GDB like this, (gdb) run -q /bin/true -ex 'b *0' -ex r -ex 'd 1' GDB should call arm_linux_fetch_inferior_registers first, and then it should call fetch_vfp_regs to fetch VFP registers. I suspect "<unavailable>" is caused by that fetch_vfp_regs is not called.
OK, here's what happens: in arm_linux_fetch_inferior_registers the last branch else if (tdep->vfp_register_count > 0 && regno >= ARM_D0_REGNUM && regno <= ARM_D0_REGNUM + tdep->vfp_register_count) fetch_vfp_regs (regcache); has tdep->vfp_register_count==16, while regno=90 (ARM_FPSCR_REGNUM). As ARM_D0_REGNUM==58, the call to fetch_vfp_regs(regcache) doesn't happen. What seems to mismatch here is that VFP register count is 16, i.e. D0-D15, but enum gdb_regnum contains values up to ARM_D31_REGNUM, thus the next value, ARM_FPSCR_REGNUM, is not reached by the comparisons. Thus it's not surprising that the code does work on VFPv3, where there're 32 VFP double-precision registers. I suppose there should be a "|| regno==ARM_FPSCR_REGNUM" or something like that inside the if-condition.
(In reply to Ruslan from comment #4) > OK, here's what happens: in arm_linux_fetch_inferior_registers the last > branch > > else if (tdep->vfp_register_count > 0 > && regno >= ARM_D0_REGNUM > && regno <= ARM_D0_REGNUM + tdep->vfp_register_count) > fetch_vfp_regs (regcache); > > has tdep->vfp_register_count==16, while regno=90 (ARM_FPSCR_REGNUM). As > ARM_D0_REGNUM==58, the call to fetch_vfp_regs(regcache) doesn't happen. > > What seems to mismatch here is that VFP register count is 16, i.e. D0-D15, > but enum gdb_regnum contains values up to ARM_D31_REGNUM, thus the next > value, ARM_FPSCR_REGNUM, is not reached by the comparisons. Thus it's not > surprising that the code does work on VFPv3, where there're 32 VFP > double-precision registers. > > I suppose there should be a "|| regno==ARM_FPSCR_REGNUM" or something like > that inside the if-condition. Indeed, I'll fix it.
The master branch has been updated by Yao Qi <qiyao@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=02ad7fc29f824a9742f8386bcf5793b81ff798f5 commit 02ad7fc29f824a9742f8386bcf5793b81ff798f5 Author: Yao Qi <yao.qi@linaro.org> Date: Fri Jul 21 16:35:23 2017 +0100 [ARM] Access FPSCR on vfpv2 GDB can fetch or store FPSCR on vfpv3, which has 32 VFP registers, but fail to do so on vfpv2, which has 16 VFP registers. GDB code is incorrect for vfpv2, else if (tdep->vfp_register_count > 0 && regno >= ARM_D0_REGNUM && regno <= ARM_D0_REGNUM + tdep->vfp_register_count) while FPSCR register number is defined as ARM_D0_REGNUM + 32. ARM_D0_REGNUM, /* VFP double-precision registers. */ ARM_D31_REGNUM = ARM_D0_REGNUM + 31, ARM_FPSCR_REGNUM, The code above uses "<=" rather than "<", in order to put FPSCR in the range, but it is only correct when tdep->vfp_register_count is 32. On vpfv2, it is 16, and FPSCR is out of the range, so fetch_vfp_regs or store_vfp_regs are not called. gdb: 2017-07-25 Yao Qi <yao.qi@linaro.org> PR tdep/21717 * arm-linux-nat.c (arm_linux_fetch_inferior_registers): Update condition for FPSCR. (arm_linux_store_inferior_registers): Likewise.
The gdb-8.0-branch branch has been updated by Yao Qi <qiyao@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=50e64da58e648ff8708935add5b2a87b4e590edf commit 50e64da58e648ff8708935add5b2a87b4e590edf Author: Yao Qi <yao.qi@linaro.org> Date: Tue Jul 25 10:15:25 2017 +0100 [ARM] Access FPSCR on vfpv2 GDB can fetch or store FPSCR on vfpv3, which has 32 VFP registers, but fail to do so on vfpv2, which has 16 VFP registers. GDB code is incorrect for vfpv2, else if (tdep->vfp_register_count > 0 && regno >= ARM_D0_REGNUM && regno <= ARM_D0_REGNUM + tdep->vfp_register_count) while FPSCR register number is defined as ARM_D0_REGNUM + 32. ARM_D0_REGNUM, /* VFP double-precision registers. */ ARM_D31_REGNUM = ARM_D0_REGNUM + 31, ARM_FPSCR_REGNUM, The code above uses "<=" rather than "<", in order to put FPSCR in the range, but it is only correct when tdep->vfp_register_count is 32. On vpfv2, it is 16, and FPSCR is out of the range, so fetch_vfp_regs or store_vfp_regs are not called. gdb: 2017-07-25 Yao Qi <yao.qi@linaro.org> PR tdep/21717 * arm-linux-nat.c (arm_linux_fetch_inferior_registers): Update condition for FPSCR. (arm_linux_store_inferior_registers): Likewise.
Patch is pushed to both master and 8.0 branch. Close it.