mirror of
https://github.com/fluencelabs/wasmer
synced 2025-04-10 11:26:05 +00:00
Custom setjmp/longjmp to avoid SEH. (will it work?)
This commit is contained in:
parent
b50fd31adb
commit
4b1d337ebe
@ -209,12 +209,14 @@ fn main() {
|
|||||||
cc::Build::new()
|
cc::Build::new()
|
||||||
.cpp(true)
|
.cpp(true)
|
||||||
.file("cpp/object_loader.cpp")
|
.file("cpp/object_loader.cpp")
|
||||||
|
.file("cpp/unwinding.s")
|
||||||
.compile("llvm-backend");
|
.compile("llvm-backend");
|
||||||
|
|
||||||
println!("cargo:rustc-link-lib=static=llvm-backend");
|
println!("cargo:rustc-link-lib=static=llvm-backend");
|
||||||
println!("cargo:rerun-if-changed=build.rs");
|
println!("cargo:rerun-if-changed=build.rs");
|
||||||
println!("cargo:rerun-if-changed=cpp/object_loader.cpp");
|
println!("cargo:rerun-if-changed=cpp/object_loader.cpp");
|
||||||
println!("cargo:rerun-if-changed=cpp/object_loader.hh");
|
println!("cargo:rerun-if-changed=cpp/object_loader.hh");
|
||||||
|
println!("cargo:rerun-if-changed=cpp/unwinding.s");
|
||||||
|
|
||||||
// Enable "nightly" cfg if the current compiler is nightly.
|
// Enable "nightly" cfg if the current compiler is nightly.
|
||||||
if rustc_version::version_meta().unwrap().channel == rustc_version::Channel::Nightly {
|
if rustc_version::version_meta().unwrap().channel == rustc_version::Channel::Nightly {
|
||||||
|
@ -4,37 +4,40 @@
|
|||||||
|
|
||||||
extern "C" void __register_frame(uint8_t *);
|
extern "C" void __register_frame(uint8_t *);
|
||||||
extern "C" void __deregister_frame(uint8_t *);
|
extern "C" void __deregister_frame(uint8_t *);
|
||||||
|
extern "C" void unwinding_setjmp(uint8_t **stack_out, void (*func)(void *), void *userdata);
|
||||||
|
[[noreturn]] extern "C" void unwinding_longjmp(uint8_t *stack_in);
|
||||||
|
|
||||||
struct UnwindPoint {
|
struct UnwindPoint {
|
||||||
UnwindPoint *prev;
|
UnwindPoint *prev;
|
||||||
jmp_buf unwind_info;
|
uint8_t *stack;
|
||||||
|
std::function<void()> *f;
|
||||||
std::unique_ptr<std::exception> exception;
|
std::unique_ptr<std::exception> exception;
|
||||||
};
|
};
|
||||||
|
|
||||||
static thread_local UnwindPoint *unwind_state = nullptr;
|
static thread_local UnwindPoint *unwind_state = nullptr;
|
||||||
|
|
||||||
|
static void unwind_payload(void *_point) {
|
||||||
|
UnwindPoint *point = (UnwindPoint *) _point;
|
||||||
|
(*point->f)();
|
||||||
|
}
|
||||||
|
|
||||||
void catch_unwind(std::function<void()>&& f) {
|
void catch_unwind(std::function<void()>&& f) {
|
||||||
UnwindPoint current;
|
UnwindPoint current;
|
||||||
current.prev = unwind_state;
|
current.prev = unwind_state;
|
||||||
|
current.f = &f;
|
||||||
unwind_state = ¤t;
|
unwind_state = ¤t;
|
||||||
|
|
||||||
bool rethrow = false;
|
unwinding_setjmp(¤t.stack, unwind_payload, (void *) ¤t);
|
||||||
|
if(current.exception) {
|
||||||
if(setjmp(current.unwind_info)) {
|
throw *current.exception;
|
||||||
rethrow = true;
|
|
||||||
} else {
|
|
||||||
f();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unwind_state = current.prev;
|
|
||||||
if(rethrow) throw *current.exception;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void unsafe_unwind(std::exception *exception) {
|
void unsafe_unwind(std::exception *exception) {
|
||||||
UnwindPoint *state = unwind_state;
|
UnwindPoint *state = unwind_state;
|
||||||
if(state) {
|
if(state) {
|
||||||
state->exception.reset(exception);
|
state->exception.reset(exception);
|
||||||
longjmp(state->unwind_info, 42);
|
unwinding_longjmp(state->stack);
|
||||||
} else {
|
} else {
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
27
lib/llvm-backend/cpp/unwinding.s
Normal file
27
lib/llvm-backend/cpp/unwinding.s
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
# (save_place, func(userdata), userdata)
|
||||||
|
.globl _unwinding_setjmp
|
||||||
|
_unwinding_setjmp:
|
||||||
|
push %r15
|
||||||
|
push %r14
|
||||||
|
push %r13
|
||||||
|
push %r12
|
||||||
|
push %rbx
|
||||||
|
push %rbp
|
||||||
|
sub $8, %rsp # 16-byte alignment
|
||||||
|
mov %rsp, (%rdi)
|
||||||
|
mov %rdx, %rdi
|
||||||
|
callq *%rsi
|
||||||
|
setjmp_ret:
|
||||||
|
add $8, %rsp
|
||||||
|
pop %rbp
|
||||||
|
pop %rbx
|
||||||
|
pop %r12
|
||||||
|
pop %r13
|
||||||
|
pop %r14
|
||||||
|
pop %r15
|
||||||
|
ret
|
||||||
|
|
||||||
|
.globl _unwinding_longjmp
|
||||||
|
_unwinding_longjmp:
|
||||||
|
mov %rdi, %rsp
|
||||||
|
jmp setjmp_ret
|
Loading…
x
Reference in New Issue
Block a user