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"); | ^~~: 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