Skip to content

Instantly share code, notes, and snippets.

@bgaff
Created April 5, 2020 01:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bgaff/943195dac5300f3b05fb19810720c95e to your computer and use it in GitHub Desktop.
Save bgaff/943195dac5300f3b05fb19810720c95e to your computer and use it in GitHub Desktop.
#include <iostream>
#include <functional>
#include <memory>
#include <cstdio>
void* _saved_return;
void* _saved_bp;
#define NO_INLINE __attribute__((noinline))
#define SET_OLD_RBP() \
asm("movq (%%rbp),%%rbp" \
: \
: \
);
#define GET_RETURN_VALUE64(VAR) \
asm ("movq %%rax,%0" \
: "=r" (VAR) \
: \
: "rax" \
);
// "movq 0x16(%%rbp),%1\n"
#define STASH_RETURN_ADDRESS() \
asm("movq 0x8(%%rbp),%0" \
: "=r" (_saved_return) \
);
#define UNSTASH_RETURN_ADDRESS() \
asm( \
"pushq (%0)\n" \
"pushq (%1)\n" \
: \
: "r" (&_saved_bp), "r" (&_saved_return) \
);
#define GET_RETURN_ADDRESS(LEVEL) \
__builtin_return_address(LEVEL)
#define SET_RETURN_ADDRESS(LEVEL, ADDR) \
asm("movq %0,0x8(%%rbp)" \
: \
: "r" (ADDR) \
);
uint64_t NO_INLINE ret_trampoline() {
UNSTASH_RETURN_ADDRESS();
uint64_t ret;
GET_RETURN_VALUE64(ret);
return ret;
}
int NO_INLINE foo () {
SET_OLD_RBP();
STASH_RETURN_ADDRESS()
SET_RETURN_ADDRESS(0, &ret_trampoline);
return 1234;
}
int main ( void ) {
uint64_t ret = foo();
std::cout << "foo() = " << ret;
return 55;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment