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,
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)));

View File

@ -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);

View File

@ -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;
}

View File

@ -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;
/**

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_WEIRD: u32 = guard_err_guard_weird;
pub const GUARD_SPENT: u32 = guard_err_guard_spent;
pub const GUARD_ERUPT: u32 = guard_err_guard_erupt;