mirror of
https://github.com/urbit/ares.git
synced 2024-11-23 00:25:49 +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,
|
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)));
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -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;
|
|
||||||
|
Loading…
Reference in New Issue
Block a user