https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89093
Bug ID: 89093
Summary: C++ exception handling clobbers d8 VFP register
Product: gcc
Version: 9.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: fw at gcc dot gnu.org
Target Milestone: ---
Target: armv7l-unknown-linux-gnueabihf
In glibc, we have a test, nptl/tst-thread-exit-clobber, that attempts to verify
if registers are properly restored by unwinding. (The actual target of the the
test is pthread_exit, but it covers more than that.)
This tests fails when running with GCC 9 libstdc++, even if glibc and the test
were built with GCC 8, and libgcc_s is replaced with the version for GCC 8
(which works when running against GCC 8 libstdc++).
In the test, the d8 register is not restored properly during unwinding, it is
set to zero. d9, d10 etc. are restored.
I noticed that in GCC 9, __gxx_personality_v0 saves the d8 VFP register:
0007b620 <__gxx_personality_v0@@CXXABI_1.3>:
7b620: e92d4ff0 push {r4, r5, r6, r7, r8, r9, sl, fp, lr}
7b624: ed2d8b02 vpush {d8}
7b628: e3a03000 mov r3, #0
7b62c: e1a08001 mov r8, r1
And it actually uses s16 and s17, apparently for spilling integer registers.
Perhaps the unwinder is not prepared to deal with that.
This happens with gcc version 9.0.0 20190119 (Red Hat 9.0.0-0.3) (GCC), built
with:
--with-tune=generic-armv7-a --with-arch=armv7-a --with-float=hard
--with-fpu=vfpv3-d16 --with-abi=aapcs-linux
--build=armv7hl-redhat-linux-gnueabi