On Sat, 3 Nov 2018 13:30:21 -0400 Steven Rostedt rostedt@goodmis.org wrote:
What I was thinking was to store a count and the functions to be called:
[original_return_address] [function_A] [function_B] [function_C] [ 3 ]
Then the trampoline that processes the return codes for ftrace (and kretprobes and everyone else) can simply do:
count = pop_shadow_stack(); for (i = 0; i < count; i++) { func = pop_shadow_stack(); func(...); } return_address = pop_shadow_stack();
That way we only need to register a function to the return handler and it will be called, without worrying about making trampolines. There will just be a single trampoline that handles all the work.
And since the most common case is a single function to call, instead of using a count, we can take advantage that kernel functions are negative numbers and do:
[original_return_address] [function_A]
----
long count;
count = pop_shadow_stack(); if (count < 0) { func = (void *)count; func(); } else { for (i = 0; i < count; i++) { [...]
The unwinder will just need to know how to handle all this :-)
-- Steve