Polymorphic Trampolines in C

Apparently, GCC defines a couple builtin functions for constructing function calls. Specifically you can save all data that could be arguments to the current function (think casting function pointers to wrong types); then call a function pointer with those arguments and capture all data that could be that function's return values; and then return those values.

This lets us define, for example, a polymorphic trampoline: void *target; void trampoline() { void *args = __builtin_apply_args(); printf("do anything before the function has been called\n"); void *ret = __builtin_apply(target, args, 0x400); printf("do anything after the function has returned\n"); __builtin_return(ret); }

Example usage: int add(int a, int b) { return a + b; } int main() { typeof(&add) add_ptr = add; printf("%d\n", add_ptr(3, 5)); target = add_ptr; add_ptr = trampoline; printf("%d\n", add_ptr(3, 5)); }

Notice the use of a hardcoded constant 0x400 here. It describes how many bytes does the stack part of the arguments take. If you specify a number too low, you risk losing data. If you specify a number too high, you will copy some extra data, but that's not a problem, the problem is that you might accidentally hit the bottom of the stack. 0x400 is a good value because, say, on Linux the arguments, environment, auxvector and other stuff that lies below the stack is usually large enough to not underflow the stack, and it's rare to see a function that passes more than 50 bytes via the stack. If your function does so, you're probably doing something wrong.

The comments section is closed