I have a void(*)(void)
function pointer to a function which is actually a void f(int)
. The point is, I don't know what kind of function it is at this point, so I can't simply cast it to void(*)(int)
. I thought I could simply prepare the stack with the argument of the function.
#include <stdio.h>
void func(int x) {
printf("%p : %d\n", &x, x);
}
int main(int argc, char* argv[]) {
int* ptr = &argc - 8;
*ptr = -1;
printf("%p : %d\n", ptr, *ptr);
void (*f)(void) = (void(*)(void)) &func;
f();
return 0;
}
This returns:
0x7ffd72ec204c : -1
0x7ffd72ec204c : 0
I would expect this to return -1
twice. However, it seems that gcc adds some code to clear the stack when a function is called, which is why func()
shows 0
instead.
Is there some kind of compiler flag to use to disable that?
I'm using gcc (Debian 4.9.2-10) 4.9.2
, but if I can get it to work in any compiler that would be enough! My uname is Linux 3.16.0-4-amd64 #1 SMP Debian 3.16.7-ckt20-1+deb8u3 (2016-01-17) x86_64 GNU/Linux
.
I've read about MUST_PASS_IN_STACK
- is that something that could help? How do I use it if yes?
I know this is not particularly best practice. This is just a theoretical exercise.
What you are trying to do is undefined behaviour. In standard C it is not possible to construct a function call with arbitrary argument types at runtime. You cannot make assumptions about the layout in which variables end up on the stack (if at all) either. You cannot even assume that function arguments are passed on the stack.
If you want to do something like this, consider looking into libraries like the libffi which does something like that by implementing a different solution for each platform and each operating system.