wip: refactoring and remove sigint handling

This commit is contained in:
Matthew LeVan 2024-02-07 16:09:57 -05:00
parent e086fbd388
commit c43b3e4cb4
5 changed files with 55 additions and 113 deletions

View File

@ -332,7 +332,6 @@ pub enum GuardError {
GuardArmor = GUARD_ARMOR as isize, GuardArmor = GUARD_ARMOR as isize,
GuardWeird = GUARD_WEIRD as isize, GuardWeird = GUARD_WEIRD as isize,
GuardSpent = GUARD_SPENT as isize, GuardSpent = GUARD_SPENT as isize,
GuardErupt = GUARD_ERUPT as isize,
} }
impl TryFrom<u32> for GuardError { impl TryFrom<u32> for GuardError {
@ -343,7 +342,6 @@ impl TryFrom<u32> for GuardError {
GUARD_ARMOR => Ok(GuardError::GuardArmor), GUARD_ARMOR => Ok(GuardError::GuardArmor),
GUARD_WEIRD => Ok(GuardError::GuardWeird), GUARD_WEIRD => Ok(GuardError::GuardWeird),
GUARD_SPENT => Ok(GuardError::GuardSpent), GUARD_SPENT => Ok(GuardError::GuardSpent),
GUARD_ERUPT => Ok(GuardError::GuardErupt),
_ => Err(()), _ => Err(()),
} }
} }
@ -523,8 +521,6 @@ pub fn call_with_guard<
ret_pp, ret_pp,
); );
eprint!("call_with_guard: error: {}\n", guard_error);
if let Ok(err) = GuardError::try_from(guard_error) { if let Ok(err) = GuardError::try_from(guard_error) {
match err { match err {
GuardError::GuardSound => { GuardError::GuardSound => {
@ -535,7 +531,8 @@ pub fn call_with_guard<
}) })
} }
GuardError::GuardArmor => { GuardError::GuardArmor => {
return Err(Error::Deterministic(Mote::Exit, D(0))); // XX
panic!("guard: couldn't place guard page\r\n");
} }
GuardError::GuardWeird => { GuardError::GuardWeird => {
return Err(Error::Deterministic(Mote::Exit, D(0))); return Err(Error::Deterministic(Mote::Exit, D(0)));
@ -543,9 +540,6 @@ pub fn call_with_guard<
GuardError::GuardSpent => { GuardError::GuardSpent => {
return Err(Error::NonDeterministic(Mote::Meme, D(0))); return Err(Error::NonDeterministic(Mote::Meme, D(0)));
} }
GuardError::GuardErupt => {
return Err(Error::NonDeterministic(Mote::Intr, D(0)));
}
} }
} else { } else {
return Err(Error::Deterministic(Mote::Exit, D(0))); return Err(Error::Deterministic(Mote::Exit, D(0)));

View File

@ -143,7 +143,7 @@ impl Context {
snapshot: Option<Snapshot>, snapshot: Option<Snapshot>,
constant_hot_state: &[HotEntry], constant_hot_state: &[HotEntry],
) -> Self { ) -> Self {
let mut stack = NockStack::new(128 << 10 << 10, 0); let mut stack = NockStack::new(64 << 10 << 10, 0);
let newt = Newt::new(); let newt = Newt::new();
let cache = Hamt::<Noun>::new(&mut stack); let cache = Hamt::<Noun>::new(&mut stack);

View File

@ -14,9 +14,7 @@
static uint64_t *guard_p = 0; static uint64_t *guard_p = 0;
static jmp_buf env_buffer; static jmp_buf env_buffer;
volatile sig_atomic_t err = guard_sound;
static void (*prev_sigsegv_handler)(int, siginfo_t *, void *); static void (*prev_sigsegv_handler)(int, siginfo_t *, void *);
static const uint64_t *(*low)(void *, void *) = 0; static const uint64_t *(*low)(void *, void *) = 0;
static const uint64_t *(*high)(void *, void *) = 0; static const uint64_t *(*high)(void *, void *) = 0;
static void *bounds = 0; static void *bounds = 0;
@ -29,33 +27,20 @@ _focus_guard()
const uint64_t *low_p = low(bounds, context); const uint64_t *low_p = low(bounds, context);
const uint64_t *high_p = high(bounds, context); const uint64_t *high_p = high(bounds, context);
// Check if we're spent already. if (low_p >= high_p ) {
if (low_p == high_p || low_p > high_p) {
return guard_spent; return guard_spent;
} }
// Check for strange situations.
if (low_p == 0 || high_p == 0) { if (low_p == 0 || high_p == 0) {
fprintf(stderr, "guard: low or high bound pointer is null\r\n"); fprintf(stderr, "guard: low or high bound pointer is null\r\n");
return guard_weird; return guard_weird;
} }
// Unmark the old guard page if one exists.
void *old_guard_p = guard_p; 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 *)low_p + ((high_p - low_p) / 2);
guard_p = (uint64_t *)((uintptr_t)guard_p & ~(GD_PAGESIZE - 1)); 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 same = old_guard_p == guard_p;
const bool left = (high_p - low_p) > GD_PAGESIZE; const bool left = (high_p - low_p) > GD_PAGESIZE;
if (same && !left) { if (same && !left) {
@ -63,62 +48,51 @@ _focus_guard()
return guard_spent; return guard_spent;
} }
else { 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) { if (mprotect(guard_p, GD_PAGESIZE, PROT_NONE) == -1) {
return guard_armor; 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; return guard_sound;
} }
static void static void
_signal_handler(int sig, siginfo_t *si, void *unused) _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) { if (guard_p == NULL) {
fprintf(stderr, "guard: no guard page\r\n"); fprintf(stderr, "guard: no guard page\r\n");
err = guard_weird;
return; return;
} }
if (si == NULL) { if (si == NULL) {
fprintf(stderr, "guard: no signal info\r\n"); fprintf(stderr, "guard: no signal info\r\n");
err = guard_weird;
return; return;
} }
switch (sig) {
case SIGSEGV:
if (si->si_addr >= (void *)guard_p && if (si->si_addr >= (void *)guard_p &&
si->si_addr < (void *)guard_p + GD_PAGESIZE) si->si_addr < (void *)guard_p + GD_PAGESIZE)
{ {
fprintf(stderr, "guard: hit: %p\r\n", si->si_addr); fprintf(stderr, "guard: hit: %p\r\n", si->si_addr);
err = _focus_guard(); guard_err err = _focus_guard();
break; if (err != guard_sound) {
fprintf(stderr, "guard: jump\r\n");
siglongjmp(env_buffer, err);
}
} }
else { else {
fprintf(stderr, "guard: weird hit: %p\r\n", si->si_addr); fprintf(stderr, "guard: weird hit: %p\r\n", si->si_addr);
if (NULL != prev_sigsegv_handler) { return;
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 (err != guard_sound) {
fprintf(stderr, "guard: long jumping\r\n");
siglongjmp(env_buffer, 1);
} }
} }
@ -152,69 +126,44 @@ guard(
void *const *ret void *const *ret
) )
{ {
// Set globals. guard_err err;
low = low_f; low = low_f;
high = high_f; high = high_f;
bounds= bounds_data; bounds= bounds_data;
context = context_p; context = context_p;
const uint64_t *low_p = low_f(bounds_data, context_p); err = _focus_guard();
const uint64_t *high_p = high_f(bounds_data, context_p); if (guard_p == NULL && err != guard_sound && err != guard_spent) {
fprintf(stderr, "guard: failed to install\r\n");
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;
goto fail; goto fail;
} }
void *result; if ((err = _register_handler()) != guard_sound) {
if (sigsetjmp(env_buffer, 1) == 0) { fprintf(stderr, "guard: failed to register handler\r\n");
result = work_f(work_data, context_p); goto fail;
*(void **)ret = result; }
err = sigsetjmp(env_buffer, 1);
if (err == guard_start) {
*(void **)ret = work_f(work_data, context_p);
return guard_sound; return guard_sound;
} }
else { else {
if (err != guard_sound) {
goto fail; goto fail;
} }
}
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. // Restore the previous signal handler.
{
struct sigaction sa; struct sigaction sa;
sa.sa_flags = SA_SIGINFO; sa.sa_flags = SA_SIGINFO;
sa.sa_sigaction = prev_sigsegv_handler; sa.sa_sigaction = prev_sigsegv_handler;
sigemptyset(&sa.sa_mask); sigemptyset(&sa.sa_mask);
sigaddset(&(sa.sa_mask), SIGSEGV); sigaddset(&(sa.sa_mask), SIGSEGV);
sigaction(SIGSEGV, &sa, NULL); 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;
} }
fprintf(stderr, "guard: fail: %d\r\n", err);
return err; return err;
} }

View File

@ -5,11 +5,11 @@
typedef enum { typedef enum {
guard_sound = 0, // job's done guard_start = 0, // setjmp
guard_armor = 1, // mprotect guard_sound = 1, // good/done
guard_weird = 2, // strange state guard_armor = 2, // mprotect
guard_spent = 3, // out of memory (bail:meme) guard_weird = 3, // strange state
guard_erupt = 4, // sigint guard_spent = 4, // out of memory (bail:meme)
} guard_err; } guard_err;
/** /**

View File

@ -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_ARMOR: u32 = guard_err_guard_armor;
pub const GUARD_WEIRD: u32 = guard_err_guard_weird; pub const GUARD_WEIRD: u32 = guard_err_guard_weird;
pub const GUARD_SPENT: u32 = guard_err_guard_spent; pub const GUARD_SPENT: u32 = guard_err_guard_spent;
pub const GUARD_ERUPT: u32 = guard_err_guard_erupt;