On Mon, Dec 16, 2024 at 11:43 AM Alexander Monakov <amona...@ispras.ru> wrote:
>
>
> On Mon, 16 Dec 2024, Florian Weimer via Gcc wrote:
>
> > I would like to provide a facility to create wrapper functions without
> > lots of argument shuffling.  To achieve that, the wrapping function and
> > the wrapped function should have the same prototype.  There will be a
> > trampoline that puts additional data somewhere (possibly including the
> > address of the wrapped function, but that interpretation is up to the
> > wrapping function) and then transfers control to the wrapper function
> > with an indirect jump (tail call).
> >
> > For signal safety, I think the hidden argument needs to be in a register
> > (instead of, say, thread-local storage).  Most System V ABI variants
> > seem to reserve a register for use by the dynamic linker, or for the
> > static chain pointer of nested functions.
> >
> > Is there a way to reuse either register for this purpose and assign it
> > to a local variable reliably at the start of the wrapper function
> > implementation?
>
> Not in a way that will work with LLVM, I'm afraid, and with GCC
> you'll have to shield wrappers from LTO:
>
> register void *r10 asm("r10");
> void f(int, int);
> void f_wrap(int a, int b)
> {
>     r10 = f;
>     f(a, b);
> }
>
> LLVM refuses to translate this. With GCC you must compile with -ffixed-r10,
> otherwise r10 is not reserved, and GCC will warn:
>
>  warning: call-clobbered register used for global register variable
>     1 | register void *r10 asm("r10");
>       |                ^~~:
>

It would be nice if this warning message would mention the -ffixed-r10
flag, to help users figure out what precisely they're supposed to do
about it.

>
> This is the only approach I'm aware of, apart of generating wrappers
> in asm (speaking of, is there some reason that wouldn't work for you?).
>
> HTH
> Alexander

Reply via email to