[Some more details confirmed.]

On 2016-Mar-9, at 12:24 PM, Mark Millard <mar...@dsl-only.net> wrote:
> 
> On 2016-Mar-9, at 11:16 AM, Mark Millard <markmi at dsl-only.net> wrote:
>> 
>> [He also includes a note about ELFV2 ABI for powerpc64le.]
>> 
>> Quoting llvm 26856 Comment 6 (he put the text in the 26856 submittal but the 
>> content also covers 26519 and most of 26844):
>> 
>>> Ulrich Weigand 2016-03-09 11:53:17 CST
>>> 
>>> Yes, there's indeed a couple of problems here, which affect different areas.
>>> 
>>> 1) On 32-bit ppc, LLVM violates the ABI by storing below the stack pointer 
>>> even though the ABI does not provide a "red zone".  This affects every 
>>> function with a stack frame, and could in theory lead to spurious crashes 
>>> when an asynchronous signal overwrites this area.  This seems to be a known 
>>> issue; the source code contains FIXME lines:
>>>   // FIXME: On PPC32 SVR4, we must not spill before claiming the stackframe.
>>> 
>>> 2) In some scenarios, registers may be spilled/restored twice to the stack. 
>>>  This happens because while most of the spilling happens in 
>>> PPCFrameLowering::spillCalleeSavedRegisters, a few selected registers are 
>>> also spilled in PPCFrameLowering::emitPrologue.  Those registers are the 
>>> frame pointer, base pointer, PIC base pointer, link register, and condition 
>>> code register.  For the latter two, code ensures that they can never be 
>>> spilled in both places (for CR, there is extra code in 
>>> spillCalleeSavedRegisters; for LR, the register is removed from SavedRegs 
>>> in determineCalleeSaves).
>>> 
>>> However, for FP, BP, and PBP, nothing ensures the registers are not spilled 
>>> twice.  It is probably *rare* for this to happen, because the register 
>>> allocator will not use those registers within the function if they're 
>>> needed for their special purpose, but it can happen in rare cases.  This 
>>> includes the case of a system unwinder routine that uses 
>>> __builtin_unwind_init, but could also include other routines that clobber 
>>> one of those registers, e.g. the following case:
>>> 
>>> void func (void);
>>> 
>>> void test (void)
>>> {
>>> func ();
>>> asm ("nop" : : : "31");
>>> }
>>> 
>>> When it happens that a register is spilled twice, the code as such still 
>>> works correctly, but the DWARF CFI unwind info associated with the routine 
>>> will be broken, which can mess up both C++ exception handling and debugging.
>>> 
>>> 3) For the specific case of system unwinder routines that use 
>>> __builtin_unwind_init and/or __builtin_eh_return, special things need to 
>>> happen in the prolog and epilog that are not required for any other 
>>> routine.  This in particular includes setting up save areas and CFI records 
>>> for the EH data registers (r3 ... r6).  [See bug #26844. ]  For the ELFv2 
>>> ABI (powerpc64le), it also include using three separate save areas for the 
>>> three caller-saved condition register fields, so that the EH logic can 
>>> overwrite their values independently.
>>> 
>>> None of this is currently implemented in LLVM, since on Linux generally GCC 
>>> is used to build the system unwind libraries, and no other code in the 
>>> system ever needs those special constructs.
>> 
>> 
>> ===
>> Mark Millard
>> markmi at dsl-only.net
> 
> One point of his note is wrong: when the 2nd "spill" of a register is after 
> it had been changed it makes a bigger difference. I commented back:
> 
> 
>> However, for FP, BP, and PBP, nothing ensures the registers are not spilled
>> twice.. . .
>> 
>> When it happens that a register is spilled twice, the code as such still
>> works correctly, but the DWARF CFI unwind info associated with the routine
>> will be broken, which can mess up both C++ exception handling and debugging.
> 
> 
> I will note that the Frame Pointer Register (r31) being saved again to the 
> same location but after it was adjusted to match the adjusted stack pointer 
> in the callee does not work correctly in that the restore of the Frame 
> Pointer for the return to the caller will restore the wrong pointer value.
> 
> If the caller then uses r31 without separately also restoring r31 first then 
> it will be addressing the wrong memory on the stack.
> 
> The observed/reported code sequence had the 2nd r31 store in the callee after 
> r31 had been adjusted to match the adjusted stack pointer in the callee.
> 
> So more than C++ exception handling and debugging is broken for the reported 
> code sequence.

The new comments are. . .

> Comment # 9 on bug 26856 from Ulrich Weigand
> (In reply to comment #8)
> 
> > (In reply to comment #6
> )
> > 
> > > However, for FP, BP, and PBP, nothing ensures the registers are not 
> > > spilled
> > > twice.. . .
> > > 
> > > When it happens that a register is spilled twice, the code as such still
> > > works correctly, but the DWARF CFI unwind info associated with the routine
> > > will be broken, which can mess up both C++ exception handling and 
> > > debugging.
> > 
> > I will note that the Frame Pointer Register (r31) being saved again to the
> > same location but after it was adjusted to match the adjusted stack pointer
> > in the callee does not work correctly in that the restore of the Frame
> > Pointer for the return to the caller will restore the wrong pointer value.
> > 
> > If the caller then uses r31 without separately also restoring r31 first then
> > it will be addressing the wrong memory on the stack.
> > 
> > The observed/reported code sequence had the 2nd r31 store in the callee
> > after r31 had been adjusted to match the adjusted stack pointer in the
> > callee.
> > 
> > So more than C++ exception handling and debugging is broken for the reported
> > code sequence.
> 
> 
> Ah, right.  I had been under the impression that the back-end would use two
> different save areas, but indeed it does use the same area, just addressed
> slightly differently.  The resulting code is then just simply incorrect.

and. . .

> Comment # 10 on bug 26856 from Ulrich Weigand
> (In reply to comment #7)
> 
> 
> > The observed behavior for the powerpc (what should be) SVR4 context is that
> > the save/restore logic for CR fields 2, 3, 4 is present but no .eh_frame
> > information is written out for the EH logic to use for CR.
> 
> 
> Huh, indeed.  This is yet another bug, which also affects functions for the
> powerpc (SVR4) ABI in general, not just unwind system routines.
> 
> This seems to be a logic issue here:
> 
>       // For SVR4, don't emit a move for the CR spill slot if we haven't
>       // spilled CRs.
>       if (isSVR4ABI && (PPC::CR2 <= Reg && Reg <= PPC::CR4)
>           && !MustSaveCR)
>         continue;
> 
> MustSaveCR is always false for 32-bit, it is only used on 64-bit.  This has 
> the
> effect that on 32-bit, we never get any CFI for the CRs.



===
Mark Millard
markmi at dsl-only.net


_______________________________________________
freebsd-toolchain@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/freebsd-toolchain
To unsubscribe, send any mail to "freebsd-toolchain-unsubscr...@freebsd.org"

Reply via email to