https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89228

            Bug ID: 89228
           Summary: ARM unwinder fails to restore vfp reg $d8
           Product: gcc
           Version: 9.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: libbacktrace
          Assignee: unassigned at gcc dot gnu.org
          Reporter: bernd.edlinger at hotmail dot de
                CC: ian at gcc dot gnu.org
  Target Milestone: ---

This makes gdb enter an endless Loop, which makes the gcc test Suite hang,
becaue the gdb process does not terminate, and the Time-out only kills
the debuggee.

A debug session is in gdb bugzilla at
https://sourceware.org/bugzilla/show_bug.cgi?id=24178

It is a bit weird, but I think the reason for this is
that __gxx_personality_v0 is saving d8 on the stack,
and restores the old d8 on return.

0036f864 <__gxx_personality_v0>:
  36f864:       e200c003        and     ip, r0, #3
  36f868:       e92d4ff0        push    {r4, r5, r6, r7, r8, r9, sl, fp, lr}
  36f86c:       e35c0001        cmp     ip, #1
  36f870:       ed2d8b02        vpush   {d8}
  36f874:       e3a03000        mov     r3, #0
  36f878:       e24dd04c        sub     sp, sp, #76     ; 0x4c
  36f87c:       e1a07002        mov     r7, r2
  36f880:       e58d100c        str     r1, [sp, #12]
  36f884:       e58d3020        str     r3, [sp, #32]
  36f888:       0a000082        beq     36fa98 <__gxx_personality_v0+0x234>
  36f88c:       e35c0002        cmp     ip, #2
  36f890:       1a000008        bne     36f8b8 <__gxx_personality_v0+0x54>
  36f894:       e59d000c        ldr     r0, [sp, #12]
  36f898:       e1a01007        mov     r1, r7
  36f89c:       eb005e60        bl      387224 <__gnu_unwind_frame>
  36f8a0:       e3500000        cmp     r0, #0
  36f8a4:       13a00009        movne   r0, #9
  36f8a8:       03a00008        moveq   r0, #8
  36f8ac:       e28dd04c        add     sp, sp, #76     ; 0x4c
  36f8b0:       ecbd8b02        vpop    {d8}
  36f8b4:       e8bd8ff0        pop     {r4, r5, r6, r7, r8, r9, sl, fp, pc}

But __gnu_unwind_frame restores the live vfp registers in violation of the ABI,
which would work, if there was a a way to avoid using vfp Registers in
the personality function.

This function is called from here:

static void __attribute__((noreturn))
unwind_phase2 (_Unwind_Control_Block * ucbp, phase2_vrs * vrs)
{
  _Unwind_Reason_Code pr_result;

  do
    {
      /* Find the entry for this routine.  */
      if (get_eit_entry (ucbp, VRS_PC(vrs)) != _URC_OK)
        abort ();

      UCB_SAVED_CALLSITE_ADDR (ucbp) = VRS_PC(vrs);

      /* Call the pr to decide what to do.  */
      pr_result = ((personality_routine) UCB_PR_ADDR (ucbp))
        (_US_UNWIND_FRAME_STARTING, ucbp, (_Unwind_Context *) vrs);
    }
  while (pr_result == _URC_CONTINUE_UNWIND);

  if (pr_result != _URC_INSTALL_CONTEXT)
    abort();

  uw_restore_core_regs (vrs, &vrs->core);
}

my conclusion so far is:
The last uw_restore_core_regs restores only r0..r15, but it should
also restore vfp regs on demand.  Note that phase2_vrs does not hold
enough space for the vfp Registers.

Reply via email to