mirror of
https://github.com/urbit/ares.git
synced 2024-11-22 15:08:54 +03:00
wip: refactoring and remove sigint handling
This commit is contained in:
parent
e086fbd388
commit
c43b3e4cb4
@ -332,7 +332,6 @@ pub enum GuardError {
|
||||
GuardArmor = GUARD_ARMOR as isize,
|
||||
GuardWeird = GUARD_WEIRD as isize,
|
||||
GuardSpent = GUARD_SPENT as isize,
|
||||
GuardErupt = GUARD_ERUPT as isize,
|
||||
}
|
||||
|
||||
impl TryFrom<u32> for GuardError {
|
||||
@ -343,7 +342,6 @@ impl TryFrom<u32> for GuardError {
|
||||
GUARD_ARMOR => Ok(GuardError::GuardArmor),
|
||||
GUARD_WEIRD => Ok(GuardError::GuardWeird),
|
||||
GUARD_SPENT => Ok(GuardError::GuardSpent),
|
||||
GUARD_ERUPT => Ok(GuardError::GuardErupt),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
@ -523,8 +521,6 @@ pub fn call_with_guard<
|
||||
ret_pp,
|
||||
);
|
||||
|
||||
eprint!("call_with_guard: error: {}\n", guard_error);
|
||||
|
||||
if let Ok(err) = GuardError::try_from(guard_error) {
|
||||
match err {
|
||||
GuardError::GuardSound => {
|
||||
@ -535,7 +531,8 @@ pub fn call_with_guard<
|
||||
})
|
||||
}
|
||||
GuardError::GuardArmor => {
|
||||
return Err(Error::Deterministic(Mote::Exit, D(0)));
|
||||
// XX
|
||||
panic!("guard: couldn't place guard page\r\n");
|
||||
}
|
||||
GuardError::GuardWeird => {
|
||||
return Err(Error::Deterministic(Mote::Exit, D(0)));
|
||||
@ -543,9 +540,6 @@ pub fn call_with_guard<
|
||||
GuardError::GuardSpent => {
|
||||
return Err(Error::NonDeterministic(Mote::Meme, D(0)));
|
||||
}
|
||||
GuardError::GuardErupt => {
|
||||
return Err(Error::NonDeterministic(Mote::Intr, D(0)));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return Err(Error::Deterministic(Mote::Exit, D(0)));
|
||||
|
@ -143,7 +143,7 @@ impl Context {
|
||||
snapshot: Option<Snapshot>,
|
||||
constant_hot_state: &[HotEntry],
|
||||
) -> Self {
|
||||
let mut stack = NockStack::new(128 << 10 << 10, 0);
|
||||
let mut stack = NockStack::new(64 << 10 << 10, 0);
|
||||
let newt = Newt::new();
|
||||
let cache = Hamt::<Noun>::new(&mut stack);
|
||||
|
||||
|
@ -14,9 +14,7 @@
|
||||
|
||||
static uint64_t *guard_p = 0;
|
||||
static jmp_buf env_buffer;
|
||||
volatile sig_atomic_t err = guard_sound;
|
||||
static void (*prev_sigsegv_handler)(int, siginfo_t *, void *);
|
||||
|
||||
static const uint64_t *(*low)(void *, void *) = 0;
|
||||
static const uint64_t *(*high)(void *, void *) = 0;
|
||||
static void *bounds = 0;
|
||||
@ -29,33 +27,20 @@ _focus_guard()
|
||||
const uint64_t *low_p = low(bounds, context);
|
||||
const uint64_t *high_p = high(bounds, context);
|
||||
|
||||
// Check if we're spent already.
|
||||
if (low_p == high_p || low_p > high_p) {
|
||||
if (low_p >= high_p ) {
|
||||
return guard_spent;
|
||||
}
|
||||
|
||||
// Check for strange situations.
|
||||
if (low_p == 0 || high_p == 0) {
|
||||
fprintf(stderr, "guard: low or high bound pointer is null\r\n");
|
||||
return guard_weird;
|
||||
}
|
||||
|
||||
// Unmark the old guard page if one exists.
|
||||
void *old_guard_p = guard_p;
|
||||
if (old_guard_p != NULL) {
|
||||
fprintf(stderr, "guard: retiring old guard page\r\n");
|
||||
if (old_guard_p != 0
|
||||
&& mprotect(old_guard_p, GD_PAGESIZE, PROT_READ | PROT_WRITE) == -1) {
|
||||
return guard_armor;
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate the new center for the guard page.
|
||||
guard_p = (uint64_t *)low_p + ((high_p - low_p) / 2);
|
||||
guard_p = (uint64_t *)((uintptr_t)guard_p & ~(GD_PAGESIZE - 1));
|
||||
|
||||
// Place the new guard page or return if we're spent.
|
||||
bool spent = false;
|
||||
const bool same = old_guard_p == guard_p;
|
||||
const bool left = (high_p - low_p) > GD_PAGESIZE;
|
||||
if (same && !left) {
|
||||
@ -63,62 +48,51 @@ _focus_guard()
|
||||
return guard_spent;
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "guard: high: %p; low: %p\r\n", high_p, low_p);
|
||||
fprintf(stderr, "guard: focused: %p; left: %u\r\n", guard_p, left);
|
||||
if (mprotect(guard_p, GD_PAGESIZE, PROT_NONE) == -1) {
|
||||
return guard_armor;
|
||||
}
|
||||
}
|
||||
|
||||
if (old_guard_p != NULL &&
|
||||
mprotect(old_guard_p, GD_PAGESIZE, PROT_READ | PROT_WRITE) == -1)
|
||||
{
|
||||
return guard_armor;
|
||||
}
|
||||
|
||||
return guard_sound;
|
||||
}
|
||||
|
||||
static void
|
||||
_signal_handler(int sig, siginfo_t *si, void *unused)
|
||||
{
|
||||
if (sig != SIGSEGV) {
|
||||
fprintf(stderr, "guard: weird signal: %d\r\n", sig);
|
||||
return;
|
||||
}
|
||||
|
||||
if (guard_p == NULL) {
|
||||
fprintf(stderr, "guard: no guard page\r\n");
|
||||
err = guard_weird;
|
||||
return;
|
||||
}
|
||||
|
||||
if (si == NULL) {
|
||||
fprintf(stderr, "guard: no signal info\r\n");
|
||||
err = guard_weird;
|
||||
return;
|
||||
}
|
||||
|
||||
switch (sig) {
|
||||
case SIGSEGV:
|
||||
if (si->si_addr >= (void *)guard_p &&
|
||||
si->si_addr < (void *)guard_p + GD_PAGESIZE)
|
||||
{
|
||||
fprintf(stderr, "guard: hit: %p\r\n", si->si_addr);
|
||||
err = _focus_guard();
|
||||
break;
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "guard: weird hit: %p\r\n", si->si_addr);
|
||||
if (NULL != prev_sigsegv_handler) {
|
||||
prev_sigsegv_handler(sig, si, unused);
|
||||
break;
|
||||
}
|
||||
else {
|
||||
err = guard_weird;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SIGINT:
|
||||
fprintf(stderr, "guard: sigint\r\n");
|
||||
err = guard_erupt;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
if (si->si_addr >= (void *)guard_p &&
|
||||
si->si_addr < (void *)guard_p + GD_PAGESIZE)
|
||||
{
|
||||
fprintf(stderr, "guard: hit: %p\r\n", si->si_addr);
|
||||
guard_err err = _focus_guard();
|
||||
if (err != guard_sound) {
|
||||
fprintf(stderr, "guard: jump\r\n");
|
||||
siglongjmp(env_buffer, err);
|
||||
}
|
||||
}
|
||||
|
||||
if (err != guard_sound) {
|
||||
fprintf(stderr, "guard: long jumping\r\n");
|
||||
siglongjmp(env_buffer, 1);
|
||||
else {
|
||||
fprintf(stderr, "guard: weird hit: %p\r\n", si->si_addr);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@ -152,69 +126,44 @@ guard(
|
||||
void *const *ret
|
||||
)
|
||||
{
|
||||
// Set globals.
|
||||
guard_err err;
|
||||
|
||||
low = low_f;
|
||||
high = high_f;
|
||||
bounds= bounds_data;
|
||||
context = context_p;
|
||||
|
||||
const uint64_t *low_p = low_f(bounds_data, context_p);
|
||||
const uint64_t *high_p = high_f(bounds_data, context_p);
|
||||
|
||||
if (guard_p == NULL) {
|
||||
guard_err focus_err = _focus_guard();
|
||||
if (focus_err != guard_sound && focus_err != guard_spent) {
|
||||
fprintf(stderr, "guard: failed to install guard page\r\n");
|
||||
err = focus_err;
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
if (_register_handler() != guard_sound) {
|
||||
err = guard_weird;
|
||||
err = _focus_guard();
|
||||
if (guard_p == NULL && err != guard_sound && err != guard_spent) {
|
||||
fprintf(stderr, "guard: failed to install\r\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
void *result;
|
||||
if (sigsetjmp(env_buffer, 1) == 0) {
|
||||
result = work_f(work_data, context_p);
|
||||
*(void **)ret = result;
|
||||
if ((err = _register_handler()) != guard_sound) {
|
||||
fprintf(stderr, "guard: failed to register handler\r\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
err = sigsetjmp(env_buffer, 1);
|
||||
if (err == guard_start) {
|
||||
*(void **)ret = work_f(work_data, context_p);
|
||||
return guard_sound;
|
||||
}
|
||||
else {
|
||||
if (err != guard_sound) {
|
||||
goto fail;
|
||||
}
|
||||
goto fail;
|
||||
}
|
||||
|
||||
fail:
|
||||
if (guard_p != NULL &&
|
||||
mprotect(guard_p, GD_PAGESIZE, PROT_READ | PROT_WRITE) == -1)
|
||||
{
|
||||
fprintf(stderr, "guard: failed to uninstall guard page\r\n");
|
||||
}
|
||||
|
||||
// Restore the previous signal handler.
|
||||
struct sigaction sa;
|
||||
sa.sa_flags = SA_SIGINFO;
|
||||
sa.sa_sigaction = prev_sigsegv_handler;
|
||||
sigemptyset(&sa.sa_mask);
|
||||
sigaddset(&(sa.sa_mask), SIGSEGV);
|
||||
sigaction(SIGSEGV, &sa, NULL);
|
||||
|
||||
switch (err) {
|
||||
case guard_armor:
|
||||
fprintf(stderr, "guard: armor error\r\n");
|
||||
break;
|
||||
case guard_weird:
|
||||
fprintf(stderr, "guard: weird error\r\n");
|
||||
break;
|
||||
case guard_spent:
|
||||
fprintf(stderr, "guard: spent error\r\n");
|
||||
break;
|
||||
case guard_erupt:
|
||||
fprintf(stderr, "guard: erupt error\r\n");
|
||||
break;
|
||||
{
|
||||
struct sigaction sa;
|
||||
sa.sa_flags = SA_SIGINFO;
|
||||
sa.sa_sigaction = prev_sigsegv_handler;
|
||||
sigemptyset(&sa.sa_mask);
|
||||
sigaddset(&(sa.sa_mask), SIGSEGV);
|
||||
sigaction(SIGSEGV, &sa, NULL);
|
||||
}
|
||||
|
||||
fprintf(stderr, "guard: fail: %d\r\n", err);
|
||||
return err;
|
||||
}
|
||||
|
@ -5,11 +5,11 @@
|
||||
|
||||
|
||||
typedef enum {
|
||||
guard_sound = 0, // job's done
|
||||
guard_armor = 1, // mprotect
|
||||
guard_weird = 2, // strange state
|
||||
guard_spent = 3, // out of memory (bail:meme)
|
||||
guard_erupt = 4, // sigint
|
||||
guard_start = 0, // setjmp
|
||||
guard_sound = 1, // good/done
|
||||
guard_armor = 2, // mprotect
|
||||
guard_weird = 3, // strange state
|
||||
guard_spent = 4, // out of memory (bail:meme)
|
||||
} guard_err;
|
||||
|
||||
/**
|
||||
|
@ -8,4 +8,3 @@ pub const GUARD_SOUND: u32 = guard_err_guard_sound;
|
||||
pub const GUARD_ARMOR: u32 = guard_err_guard_armor;
|
||||
pub const GUARD_WEIRD: u32 = guard_err_guard_weird;
|
||||
pub const GUARD_SPENT: u32 = guard_err_guard_spent;
|
||||
pub const GUARD_ERUPT: u32 = guard_err_guard_erupt;
|
||||
|
Loading…
Reference in New Issue
Block a user