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

--- Comment #18 from Josh Poimboeuf <jpoimboe at redhat dot com> ---
(In reply to H.J. Lu from comment #17)
> (In reply to Josh Poimboeuf from comment #7)
> > Putting "sp" in the clobbers list is something that was suggested to me on
> > the GCC mailing list a while back.  And, other than this rare bug, it seems
> > to do exactly what we want, which is, force GCC to save the frame pointer
> > before inserting the inline asm.  We need that to happen when we put a
> > "call" instruction inside the inline asm, so that we can get a reliable
> > stack trace from the called function.
> > 
> > I know that putting "sp" in the clobbers list is an undocumented "feature",
> > so maybe it is user error.  However it would be nice to have something like
> > this as a real feature.  Either with "sp", or maybe a new clobbers keyword
> > like "frame". 
> > 
> > Would that be feasible?
> 
> Can you use something like
> 
> unsigned long paravirt_read_pmc(void)
> {
>   register char *frame __asm__("ebp");
>   unsigned long __eax;
>   asm volatile("# foo" : "=a" (__eax)
>                : "r" (frame)
>                : "memory", "cc");
>   return __eax;
> }
> 
> That is your asm statement needs frame pointer.

That works, with frame pointers enabled (-fno-omit-frame-pointer).  But with
-fomit-frame-pointer, it causes GCC to save rbp on the stack, which is not
ideal.

There's something similar, which does exactly what we need: make "rsp" an
input/output constraint:

  register void *__sp asm("rsp");

  static inline function foo(void)
  {
    asm volatile("call bar" : "+r" (__sp));
  }

That forces a frame pointer when frame pointers are enabled, and does nothing
when frame pointers are disabled.  So I think we'll go with that solution for
now.

(Note that "__sp" is a global variable due to a compatibility issue with the
clang compiler.)

Reply via email to