Reputation: 43
I would like to know under which circumstances a C function can runtime change its return address, when called from the same function.
I have noticed it happening in a series of test on a low level code I've developed. This is a snippet that shows how I retrieve the two pointers:
#include <stdint.h>
uintptr_t foo() {
// Fetch the current IP and SP
uintptr_t ip = (uintptr_t)__builtin_return_address(0);
register void* rsp asm("sp");
uintptr_t sp = (uintptr_t)rsp;
return ip + sp; // just to avoid that they are optimized away.
}
void bar () {
foo();
}
When I run my test and call bar
from different functions, I see the values of IP changing (not very frequently, only once in a long series of test).
I though about the fact my compiler may inline the functions. But, I see the error happening even with __attribute__((noinline))
applied to both functions.
I know not being reliable as it may be optimized away.
Do you have any other explanation or solution for this problem?
I'm compiling using gcc 4.7.2 under GNU/Linux Kernel 3.10.39.
Upvotes: 2
Views: 196
Reputation: 91139
The "return address" is the address where the function returns to. If you call it from several places, it is immediately clear why this happens.
The stack pointer depends on the depth of the stack we are currently in and thus depends on the call history: if main()
calls a()
which calls b()
which calls foo()
, you have a different SP
than if main()
calls foo()
directly.
Upvotes: 4