Bug 267361 - EINVAL accessing fpcsr for armv7 process on arm64 kernel
Summary: EINVAL accessing fpcsr for armv7 process on arm64 kernel
Status: Closed FIXED
Alias: None
Product: Base System
Classification: Unclassified
Component: arm (show other bugs)
Version: 13.1-RELEASE
Hardware: arm64 Any
: --- Affects Some People
Assignee: freebsd-arm (Nobody)
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2022-10-26 10:13 UTC by Robert Clausecker
Modified: 2023-02-16 11:32 UTC (History)
2 users (show)

See Also:


Attachments
Patch adapted for 13.1 (3.44 KB, patch)
2022-10-28 17:08 UTC, Olivier Houchard
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Robert Clausecker freebsd_committer freebsd_triage 2022-10-26 10:13:43 UTC
To reproduce: install devel/gdb from ports.  Then type

    gdb /usr/bin/true
    starti
    info registers

Expected output:

(gdb) info registers
r0             0x0                 0
r1             0x0                 0
r2             0x0                 0
r3             0x0                 0
r4             0x0                 0
r5             0x0                 0
r6             0x0                 0
r7             0x0                 0
r8             0x0                 0
r9             0x0                 0
r10            0x0                 0
r11            0x0                 0
r12            0x0                 0
sp             0xbfbfec9c          0xbfbfec9c
lr             0x20054380          537215872
pc             0x20054380          0x20054380 <rtld_start>
cpsr           0x10                16
fpscr          0x2000000           33554432
tpidruro       <unavailable>

Actual output:

(gdb) info registers
r0             0xffffdb58          4294957912
r1             0x0                 0
r2             0x0                 0
r3             0x0                 0
r4             0x0                 0
r5             0x0                 0
r6             0x0                 0
r7             0x0                 0
r8             0x0                 0
r9             0x0                 0
r10            0x0                 0
r11            0x0                 0
r12            0x0                 0
sp             0xffffdb58          0xffffdb58
lr             0x40054380          1074086784
pc             0x40054380          0x40054380 <rtld_start>
cpsr           0x10                16
Couldn't get registers: Invalid argument.

The "expected output" is from an armv7 system.  I have tested in an armv7 FreeBSD 13.1 jail on arm64 FreeBSD 13.1.  The gdb version is 12.1 from ports.
Comment 1 Mark Millard 2022-10-26 16:08:56 UTC
Looks to me more likely a gdb issue than a base system issue.
Likely need to have progressed farther into the function
prelude for things to look right in gdb.

Also: Not 13.1-RELEASE specific. From a main [so: 14] Cortex-A72
system (aarch64), via a chroot that shows (long output line split
for readability):

# uname -apKU
FreeBSD CA72_16Gp_ZFS 14.0-CURRENT FreeBSD 14.0-CURRENT #64
main-n258610-ba7319e9091b-dirty: Fri Oct 21 22:34:11 PDT 2022
root@CA72_16Gp_ZFS:/usr/obj/BUILDs/main-CA72-nodbg-clang/usr/main-src/arm64.aarch64/sys/GENERIC-NODBG-CA72
arm armv7 1400072 1400072

I get:

# gdb /usr/bin/true
GNU gdb (GDB) 12.1 [GDB v12.1 for FreeBSD]
Copyright (C) 2022 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "armv7-portbld-freebsd14.0".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from /usr/bin/true...
Reading symbols from /usr/lib/debug//usr/bin/true.debug...
(gdb) starti
Starting program: /usr/bin/true 

Program stopped.
rtld_start () at /usr/main-src/libexec/rtld-elf/arm/rtld_start.S:40
40      /usr/main-src/libexec/rtld-elf/arm/rtld_start.S: No such file or directory.
(gdb) info registers
r0             0xffffdc88          4294958216
r1             0x0                 0
r2             0x0                 0
r3             0x0                 0
r4             0x0                 0
r5             0x0                 0
r6             0x0                 0
r7             0x0                 0
r8             0x0                 0
r9             0x0                 0
r10            0x0                 0
r11            0x0                 0
r12            0x0                 0
sp             0xffffdc88          0xffffdc88
lr             0x40054380          1074086784
pc             0x40054380          0x40054380 <rtld_start>
cpsr           0x10                16
Couldn't get registers: Invalid argument.
Comment 2 Mark Millard 2022-10-26 16:16:40 UTC
(In reply to Mark Millard from comment #1)

Interesting. I tried lldb which did not allow stepi yet because the processes had nto been started. So I went back to gdb and got the same general sort of notice:

# gdb /usr/bin/true
GNU gdb (GDB) 12.1 [GDB v12.1 for FreeBSD]
Copyright (C) 2022 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "armv7-portbld-freebsd14.0".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from /usr/bin/true...
Reading symbols from /usr/lib/debug//usr/bin/true.debug...
(gdb) stepi
The program is not being run.

Somehow the first attempt in the chroot is handled differently.
Comment 3 Mark Millard 2022-10-26 16:22:11 UTC
(In reply to Mark Millard from comment #2)

I tried exiting the chroot and starting a new one and using
starti instead of stepi :

# gdb /usr/bin/true
GNU gdb (GDB) 12.1 [GDB v12.1 for FreeBSD]
Copyright (C) 2022 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "armv7-portbld-freebsd14.0".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from /usr/bin/true...
Reading symbols from /usr/lib/debug//usr/bin/true.debug...
(gdb) starti
Starting program: /usr/bin/true 

Program stopped.
rtld_start () at /usr/main-src/libexec/rtld-elf/arm/rtld_start.S:40
40      /usr/main-src/libexec/rtld-elf/arm/rtld_start.S: No such file or directory.
(gdb) info registers
r0             0xffffdc88          4294958216
r1             0x0                 0
r2             0x0                 0
r3             0x0                 0
r4             0x0                 0
r5             0x0                 0
r6             0x0                 0
r7             0x0                 0
r8             0x0                 0
r9             0x0                 0
r10            0x0                 0
r11            0x0                 0
r12            0x0                 0
sp             0xffffdc88          0xffffdc88
lr             0x40054380          1074086784
pc             0x40054380          0x40054380 <rtld_start>
cpsr           0x10                16
Couldn't get registers: Invalid argument.
(gdb) bt
#0  rtld_start () at /usr/main-src/libexec/rtld-elf/arm/rtld_start.S:40
Backtrace stopped: previous frame identical to this frame (corrupt stack?)
(gdb) 

This seems to be repeatable in the chroot session.

It also shows some context for what context is being reported on
by the info registers: It is not yet even near main().
Comment 4 Mark Millard 2022-10-26 16:41:47 UTC
(In reply to Mark Millard from comment #3)

Trying lldb (once I figured out how to do about the same in it):

# lldb /usr/bin/true
(lldb) target create "/usr/bin/true"
Current executable set to '/usr/bin/true' (arm).
(lldb) process launch -s
Process 86479 launched: '/usr/bin/true' (arm)
(lldb) register read
General Purpose Registers:
        r0 = 0xffffdca4
        r1 = 0x00000000
        r2 = 0x00000000
        r3 = 0x00000000
        r4 = 0x00000000
        r5 = 0x00000000
        r6 = 0x00000000
        r7 = 0x00000000
        r8 = 0x00000000
        r9 = 0x00000000
       r10 = 0x00000000
       r11 = 0x00000000
       r12 = 0x00000000
        sp = 0xffffdca4
        lr = 0x40054380
        pc = 0x40054380
      cpsr = 0x00000010

(lldb) 

No evidence of "Couldn't get registers: Invalid argument."

This also suggests the issue is just a gdb issue, not a
base system issue.
Comment 5 Robert Clausecker freebsd_committer freebsd_triage 2022-10-26 17:05:27 UTC
(In reply to Mark Millard from comment #4)

If it's a gdb issue, then why does it work on a native armv7 system?

Could this perhaps be related to an issue similar to bug #259187?  I.e. perhaps the arm64 kernel denies access to the VFP state before the first VFP instruction has been issued?
Comment 6 Mark Millard 2022-10-26 18:12:15 UTC
(In reply to Robert Clausecker from comment #5)

May be lldb does not try to access what gdb accesses?
If so, my example lldb usage might not mean much.
Comment 7 commit-hook freebsd_committer freebsd_triage 2022-10-27 21:30:52 UTC
A commit in branch main references this bug:

URL: https://cgit.FreeBSD.org/src/commit/?id=d78c2cd831d346b94c00c72b5a94a1a4f0dd3e53

commit d78c2cd831d346b94c00c72b5a94a1a4f0dd3e53
Author:     Olivier Houchard <cognet@FreeBSD.org>
AuthorDate: 2022-10-27 21:25:59 +0000
Commit:     Olivier Houchard <cognet@FreeBSD.org>
CommitDate: 2022-10-27 21:25:56 +0000

    arm64: Implement cpu_ptrace().

    Add a minimal implementation of cpu_ptrace() for arm64. It is only used to
    get/set VFP registers for 32bits binaries, as it is apparently what we use
    there, instead of the MI PT_GETFPREGS/PT_SETFPREGS.

    PR:     267361
    MFC After: 1 week

 sys/arm64/arm64/ptrace_machdep.c | 30 ++++++++++++++++++++++++++++++
 sys/arm64/include/ptrace.h       | 10 ++++++++++
 2 files changed, 40 insertions(+)
Comment 8 Robert Clausecker freebsd_committer freebsd_triage 2022-10-28 15:22:07 UTC
@cognet thank you for the patch!

Could you attach a port of the patch to stable/13 so I can test it on my system?  While the patch against main applies, it does not compile due to missing functions.  It appears some static functions had been shuffled around between stable/13 and main and I am not sure what needs to be backported to make it work.
Comment 9 Olivier Houchard freebsd_committer freebsd_triage 2022-10-28 17:08:28 UTC
Created attachment 237693 [details]
Patch adapted for 13.1

Hi Robert,

Sure ! Here it comes. It does compile on 13.1, and should probably work, please let me know how it goes.
Comment 10 Robert Clausecker freebsd_committer freebsd_triage 2022-10-30 23:58:36 UTC
I can confirm that this patch fixes the problem for me on FreeBSD 13.1!
Thank you for the prompt fix!
Comment 11 commit-hook freebsd_committer freebsd_triage 2022-11-04 23:51:24 UTC
A commit in branch stable/13 references this bug:

URL: https://cgit.FreeBSD.org/src/commit/?id=f487dbef66a93cff73b83935693518a685e16f5a

commit f487dbef66a93cff73b83935693518a685e16f5a
Author:     Olivier Houchard <cognet@FreeBSD.org>
AuthorDate: 2022-10-27 21:25:59 +0000
Commit:     Olivier Houchard <cognet@FreeBSD.org>
CommitDate: 2022-11-04 23:29:09 +0000

    arm64: Implement cpu_ptrace().

    Add a minimal implementation of cpu_ptrace() for arm64. It is only used to
    get/set VFP registers for 32bits binaries, as it is apparently what we use
    there, instead of the MI PT_GETFPREGS/PT_SETFPREGS.

    PR:     267361
    MFC After: 1 week

    (cherry picked from commit d78c2cd831d346b94c00c72b5a94a1a4f0dd3e53)
    Signed-off-by: Olivier Houchard <cognet@FreeBSD.org>

 sys/arm64/arm64/ptrace_machdep.c | 30 ++++++++++++++++++++++++++++++
 sys/arm64/include/ptrace.h       | 10 ++++++++++
 2 files changed, 40 insertions(+)
Comment 12 Robert Clausecker freebsd_committer freebsd_triage 2023-02-16 11:32:13 UTC
I guess we are done here.