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