Messages in this thread | | | Date | Wed, 18 Nov 2020 15:12:26 +0100 | From | Peter Zijlstra <> | Subject | Re: violating function pointer signature |
| |
On Wed, Nov 18, 2020 at 02:59:29PM +0100, Florian Weimer wrote: > * Peter Zijlstra: > > > I think that as long as the function is completely empty (it never > > touches any of the arguments) this should work in practise. > > > > That is: > > > > void tp_nop_func(void) { } > > > > can be used as an argument to any function pointer that has a void > > return. In fact, I already do that, grep for __static_call_nop(). > > You can pass it as a function parameter, but in general, you cannot > call the function with a different prototype. Even trivial > differences such as variadic vs non-variadic prototypes matter.
I don't think any tracepoint uses variadic argument.
> The default Linux calling conventions are all of the cdecl family, > where the caller pops the argument off the stack. You didn't quote > enough to context to tell whether other calling conventions matter in > your case.
This is strictly in-kernel, and I think we're all cdecl, of which the important part is caller-cleanup. The function compiles to:
RET
so whatever the arguments are is irrelevant.
> > I'm not sure what the LLVM-CFI crud makes of it, but that's their > > problem. > > LTO can cause problems as well, particularly with whole-program > optimization.
I don't think LTO can de-virtualize a dynamic array of function pointers, so there's very little risk. That said, the __static_call_nop case, where everything is inlined, is compiled sub-optimally for both LLVM and GCC.
| |