I have recently been trying to use the __builtin_extract_return_addr function described here (https://gcc.gnu.org/onlinedocs/gcc/Return-Address.html) to obtain the encoded value of the RSP pointer. I am intentionally avoiding using __builtin_return_address(0) function, and solely trying to get the return address value to the caller using the RSP register.
The description of this function is as stated:
void * __builtin_extract_return_addr (void * addr)
The address as returned by __builtin_return_address may have to be fed through this function to get the actual encoded address. If no fixup is needed, this function simply passes through addr.
From my understanding, it seems as this function can take the arbitrary address and obtain the actual encoded address. (e.g., if
RSP 0x7fffffffe458 —▸ 0x40058e (main+14)
,
then using __builtin_extract_return_addr(0x7fffffffe458) should be 0x40058e
)
So I have this very simple test code I have been using to learn a bit about this, but not getting the values I am trying to get so I wanted to ask the question in the StackOverflow:
void print_sp() {
register void *sp asm ("rsp");
printf("%p\n", __builtin_extract_return_addr(sp));
void *addr = 0x7fffffffe458;
printf("%p\n", __builtin_extract_return_addr((addr)));
printf("%p\n", __builtin_return_address(0)); // I am trying to avoid using this
}
int main() {
print_sp();
}
In the first two lines of print_sp() function, I'm reading and printing the RSP register value, then using the builtin_extract_return_addr to see if I can get the encoded address of what is stored in the RSP register. This was a failure as I debugged using gdb, I am understanding it as the RSP register value at the time of this line is called will not have the return address to the caller.
In the second two lines of print_sp() function, I am hardcoding the void *addr to the value of 0x7fffffffe458, and then using this address value to see if I can get the decoded return address. The reason is that at the time of ret
instruction, the RSP value as shown
here is the following:
RSP 0x7fffffffe458 —▸ 0x40058e (main+14) ◂— mov eax, 0
To summarize, I am trying to get the return address value of 0x400578 without using the __builtin_return_address(0) value.
I have also tried to implement addq $8, %%rsp; jmpq -8(%%rsp)
using the inline assembly but to no avail. Something like this?
uintptr_t result;
asm volatile ( "mov %%rsp, %[value]\n\t"
"addq $8, %[value]\n\t"
: [value]"=a"(result)
: );
uintptr_t caller_address = (uintptr_t)__builtin_extract_return_addr(result);
Here is the disassembly of print_sp and main() function
Also, here are a few similar questions posted in the StackOverflow that I took a look: Retq instruction, where does it return Meaning of 0x8($rsp)
I hope the question makes sense. Please let me know if there is anything unclear and I will try to clarify them right away.
Thank you,