Last active
February 22, 2022 12:54
-
-
Save StefanoBelli/d3b63a4c132e89bfb0e26b9ffadc8ba8 to your computer and use it in GitHub Desktop.
setjmp experiments
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <setjmp.h> | |
typedef unsigned long long __u64; | |
#define get_rsp(into) \ | |
__asm__ __volatile__("movq %%rsp, %0;" : "=m"(into) :: "memory") | |
#ifndef PUSH_RET_ADDR | |
# define __maybe_noreturn __attribute__((noreturn)) | |
#else | |
# define __maybe_noreturn | |
#endif | |
static jmp_buf env; | |
void setter() { | |
__u64 rsp; | |
get_rsp(rsp); | |
int x = 0xcafebabe; | |
if(setjmp(env) == 1) { | |
get_rsp(rsp); | |
printf("setter(rsp=0x%x): refetched rsp\n", rsp); | |
} | |
printf("setter(rsp=0x%x): \"x\" has value 0x%x\n", rsp, x); | |
} | |
__maybe_noreturn void jumper() { | |
__u64 rsp; | |
get_rsp(rsp); | |
int y = 0xdeadbeef; | |
printf("jumper(rsp=0x%x): performing long jump\n", rsp); | |
longjmp(env, 1); | |
} | |
int main() { | |
setter(); | |
jumper(); | |
puts("gracefully exiting..."); | |
return EXIT_SUCCESS; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <csetjmp> | |
#ifdef MAKE_LONGJMP | |
# define __maybe_noreturn __attribute__((noreturn)) | |
# define __maybe_longjmp(b,v) longjmp(b,v) | |
#else | |
# define __maybe_noreturn | |
# define __maybe_longjmp(unused_1, unused_2) | |
#endif | |
static jmp_buf env; | |
class ResourceHolder { | |
public: | |
ResourceHolder() { | |
std::cout << "\t\tResourceHolder::<ctor> -- acquisition\n"; | |
} | |
~ResourceHolder() { | |
std::cout << "\t\tResourceHolder::<dtor> -- release\n"; | |
} | |
}; | |
__maybe_noreturn void f() { | |
ResourceHolder r; | |
__maybe_longjmp(env, 1); | |
} | |
int main() { | |
std::cout << "starting\n"; | |
if(!setjmp(env)) { | |
std::cout << "\tenv set nonlocal jump\n\tcalling f()\n"; | |
f(); | |
std::cout << "\tback from f() via ret instruction execution\n"; | |
} else { | |
std::cout << "\tback from f() via long jump\n"; | |
} | |
std::cout << "exiting...\n"; | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment