Richard Henderson <r...@redhat.com> writes:
> On 02/05/2014 07:58 AM, Jakub Jelinek wrote:
>> On Wed, Feb 05, 2014 at 03:32:22PM +0000, Richard Sandiford wrote:
>>> I think at the moment we're relying on the "DW_CFA_offset 15"s to
>>> provide correct %r15 values on eh_return.  Every non-leaf function
>>> saves the stack pointer and the unwind routines track the %r15 save
>>> slots like they would track any call-saved register.  In other words,
>>> the final eh_return %r15 comes directly from a save slot, without any
>>> CFA-specific handling.  If some frames omit the CFI for the %r15 save
>>> then we'll just keep the save slot from the previous (inner) frame instead.
>> 
>> CCing Richard Henderson into the discussion.
>
> If the sp is saved for a given frame, we'll use that instead of the CFA when
> unwinding to a previous frame.  That should be unaffected by whether or not sp
> is saved for any particular frame.
>
> There appears to be code in uw_install_context_1 to handle a mix of sp-saving
> and non-sp-saving frames.  Given that s390 is pretty much the only target that
> uses these paths, I suppose it could be broken.  But if it is, it would surely
> be better to fix than just say "it doesn't work".

OK.  When I was looking at it earlier today, the reason it didn't work
seemed to be that if %r15 wasn't saved for a particular frame, the context
would inherit the %r15 save slot for the previous frame, just like when
some functions use and save a particular call-saved register and some don't.
So we would only get to uw_install_context_1 without a %r15 slot if none
of the frames had one.

In other words, the reason seemed to be that the _Unwind_SetGRPtr in:

#ifdef EH_RETURN_STACKADJ_RTX
  /* Special handling here: Many machines do not use a frame pointer,
     and track the CFA only through offsets from the stack pointer from
     one frame to the next.  In this case, the stack pointer is never
     stored, so it has no saved address in the context.  What we do
     have is the CFA from the previous stack frame.

     In very special situations (such as unwind info for signal return),
     there may be location expressions that use the stack pointer as well.

     Do this conditionally for one frame.  This allows the unwind info
     for one frame to save a copy of the stack pointer from the previous
     frame, and be able to use much easier CFA mechanisms to do it.
     Always zap the saved stack pointer value for the next frame; carrying
     the value over from one frame to another doesn't make sense.  */

  _Unwind_SpTmp tmp_sp;

  if (!_Unwind_GetGRPtr (&orig_context, __builtin_dwarf_sp_column ()))
    _Unwind_SetSpColumn (&orig_context, context->cfa, &tmp_sp);
  _Unwind_SetGRPtr (context, __builtin_dwarf_sp_column (), NULL);
#endif

was conditional on EH_RETURN_STACKADJ_RTX being defined.  It looked at
first glance like things would work if that call was moved outside,
so that we never inherit save slots for the stack pointer.  Does that
make sense?  I can give it a go tomorrow if so.

Thanks,
Richard

Reply via email to