Passing a hidden argument in a dedicated register
Eric Gallager
egall@gwmail.gwu.edu
Fri Dec 27 23:14:49 GMT 2024
On Mon, Dec 16, 2024 at 11:43 AM Alexander Monakov <amonakov@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
More information about the Gcc
mailing list