mirror of
https://github.com/urbit/shrub.git
synced 2024-12-18 15:55:00 +03:00
u3: adds facade for u3e_fault(), refactors error handling
This commit is contained in:
parent
d043a42128
commit
c3821c3325
@ -47,6 +47,14 @@
|
|||||||
u3e_image sou_u; // south segment
|
u3e_image sou_u; // south segment
|
||||||
} u3e_pool;
|
} u3e_pool;
|
||||||
|
|
||||||
|
/* u3e_flaw: loom fault result.
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
u3e_flaw_sham = 0, // bogus state
|
||||||
|
u3e_flaw_base = 1, // vm fail (mprotect)
|
||||||
|
u3e_flaw_meme = 2, // bail:meme
|
||||||
|
u3e_flaw_good = 3 // handled
|
||||||
|
} u3e_flaw;
|
||||||
|
|
||||||
/** Globals.
|
/** Globals.
|
||||||
**/
|
**/
|
||||||
@ -61,10 +69,10 @@
|
|||||||
|
|
||||||
/** Functions.
|
/** Functions.
|
||||||
**/
|
**/
|
||||||
/* u3e_fault(): handle a memory event with libsigsegv protocol.
|
/* u3e_fault(): handle a memory fault.
|
||||||
*/
|
*/
|
||||||
c3_i
|
u3e_flaw
|
||||||
u3e_fault(void* adr_v, c3_i ser_i);
|
u3e_fault(u3_post low_p, u3_post hig_p, u3_post off_p);
|
||||||
|
|
||||||
/* u3e_save(): update the checkpoint.
|
/* u3e_save(): update the checkpoint.
|
||||||
*/
|
*/
|
||||||
|
@ -210,107 +210,67 @@ _ce_ward_post(c3_w nop_w, c3_w sop_w)
|
|||||||
|
|
||||||
/* _ce_ward_clip(): hit the guard page.
|
/* _ce_ward_clip(): hit the guard page.
|
||||||
*/
|
*/
|
||||||
static inline c3_i
|
static inline u3e_flaw
|
||||||
_ce_ward_clip(void)
|
_ce_ward_clip(c3_w nop_w, c3_w sop_w)
|
||||||
{
|
{
|
||||||
const c3_w old_w = u3P.gar_w;
|
c3_w old_w = u3P.gar_w;
|
||||||
c3_w nop_w, sop_w;
|
|
||||||
{
|
|
||||||
u3_post low_p, hig_p;
|
|
||||||
|
|
||||||
if ( !u3R ) {
|
|
||||||
low_p = 1;
|
|
||||||
hig_p = u3C.wor_i - 1;
|
|
||||||
}
|
|
||||||
else if ( c3y == u3a_is_north(u3R) ) {
|
|
||||||
low_p = u3R->hat_p;
|
|
||||||
hig_p = u3R->cap_p;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
low_p = u3R->cap_p;
|
|
||||||
hig_p = u3R->hat_p;
|
|
||||||
}
|
|
||||||
|
|
||||||
nop_w = (low_p - 1) >> u3a_page;
|
|
||||||
sop_w = hig_p >> u3a_page;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( !u3P.gar_w || ((nop_w < u3P.gar_w) && (sop_w > u3P.gar_w)) ) {
|
if ( !u3P.gar_w || ((nop_w < u3P.gar_w) && (sop_w > u3P.gar_w)) ) {
|
||||||
fprintf(stderr, "loom: ward bogus (>%u %u %u<)\r\n",
|
fprintf(stderr, "loom: ward bogus (>%u %u %u<)\r\n",
|
||||||
nop_w, u3P.gar_w, sop_w);
|
nop_w, u3P.gar_w, sop_w);
|
||||||
return 0;
|
return u3e_flaw_sham;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( sop_w <= (nop_w + 1) ) {
|
if ( sop_w <= (nop_w + 1) ) {
|
||||||
u3m_signal(c3__meme); // doesn't return
|
return u3e_flaw_meme;
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( _ce_ward_post(nop_w, sop_w) ) {
|
if ( _ce_ward_post(nop_w, sop_w) ) {
|
||||||
return 0;
|
return u3e_flaw_base;
|
||||||
}
|
}
|
||||||
|
|
||||||
c3_assert( old_w != u3P.gar_w );
|
c3_assert( old_w != u3P.gar_w );
|
||||||
return 1;
|
|
||||||
|
return u3e_flaw_good;
|
||||||
}
|
}
|
||||||
#endif /* ifdef U3_GUARD_PAGE */
|
#endif /* ifdef U3_GUARD_PAGE */
|
||||||
|
|
||||||
/* u3e_fault(): handle a memory event with libsigsegv protocol.
|
/* u3e_fault(): handle a memory fault.
|
||||||
*/
|
*/
|
||||||
c3_i
|
u3e_flaw
|
||||||
u3e_fault(void* adr_v, c3_i ser_i)
|
u3e_fault(u3_post low_p, u3_post hig_p, u3_post off_p)
|
||||||
{
|
{
|
||||||
// Let the stack overflow handler run.
|
c3_w pag_w = off_p >> u3a_page;
|
||||||
if ( 0 == ser_i ) {
|
c3_w blk_w = pag_w >> 5;
|
||||||
return 0;
|
c3_w bit_w = pag_w & 31;
|
||||||
}
|
|
||||||
|
|
||||||
// XX u3l_log avoid here, as it can
|
|
||||||
// cause problems when handling errors
|
|
||||||
|
|
||||||
c3_w* adr_w = (c3_w*) adr_v;
|
|
||||||
|
|
||||||
if ( (adr_w < u3_Loom) || (adr_w >= (u3_Loom + u3C.wor_i)) ) {
|
|
||||||
fprintf(stderr, "address %p out of loom!\r\n", adr_w);
|
|
||||||
fprintf(stderr, "loom: [%p : %p)\r\n", u3_Loom, u3_Loom + u3C.wor_i);
|
|
||||||
c3_assert(0);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
u3p(c3_w) adr_p = u3a_outa(adr_w);
|
|
||||||
c3_w pag_w = adr_p >> u3a_page;
|
|
||||||
c3_w blk_w = (pag_w >> 5);
|
|
||||||
c3_w bit_w = (pag_w & 31);
|
|
||||||
|
|
||||||
#ifdef U3_GUARD_PAGE
|
#ifdef U3_GUARD_PAGE
|
||||||
if ( pag_w == u3P.gar_w ) {
|
if ( pag_w == u3P.gar_w ) {
|
||||||
if ( !_ce_ward_clip() ) {
|
u3e_flaw fal_e = _ce_ward_clip(low_p >> u3a_page, hig_p >> u3a_page);
|
||||||
c3_assert(0);
|
|
||||||
return 0;
|
if ( u3e_flaw_good != fal_e ) {
|
||||||
|
return fal_e;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !(u3P.dit_w[blk_w] & (1 << bit_w)) ) {
|
if ( !(u3P.dit_w[blk_w] & (1 << bit_w)) ) {
|
||||||
fprintf(stderr, "loom: strange guard (%d)\r\n", pag_w);
|
fprintf(stderr, "loom: strange guard (%d)\r\n", pag_w);
|
||||||
c3_assert(0);
|
return u3e_flaw_sham;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
if ( 0 != (u3P.dit_w[blk_w] & (1 << bit_w)) ) {
|
if ( u3P.dit_w[blk_w] & (1 << bit_w) ) {
|
||||||
fprintf(stderr, "strange page: %d, at %p, off %x\r\n", pag_w, adr_w, adr_p);
|
fprintf(stderr, "loom: strange page (%d): %x\r\n", pag_w, off_p);
|
||||||
c3_assert(0);
|
return u3e_flaw_sham;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
u3P.dit_w[blk_w] |= (1 << bit_w);
|
u3P.dit_w[blk_w] |= (1 << bit_w);
|
||||||
|
|
||||||
if ( _ce_flaw_protect(pag_w) ) {
|
if ( _ce_flaw_protect(pag_w) ) {
|
||||||
c3_assert(0);
|
return u3e_flaw_base;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return u3e_flaw_good;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* _ce_image_open(): open or create image.
|
/* _ce_image_open(): open or create image.
|
||||||
|
@ -1687,12 +1687,70 @@ _cm_limits(void)
|
|||||||
# endif
|
# endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_cm_water(u3_post* low_p, u3_post* hig_p)
|
||||||
|
{
|
||||||
|
c3_w top_w, bot_w;
|
||||||
|
|
||||||
|
if ( c3y == u3a_is_north(u3R) ) {
|
||||||
|
*low_p = u3R->hat_p - 1;
|
||||||
|
*hig_p = u3R->cap_p;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
*low_p = u3R->cap_p - 1;
|
||||||
|
*hig_p = u3R->hat_p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* u3m_fault(): handle a memory event with libsigsegv protocol.
|
/* u3m_fault(): handle a memory event with libsigsegv protocol.
|
||||||
*/
|
*/
|
||||||
c3_i
|
c3_i
|
||||||
u3m_fault(void* adr_v, c3_i ser_i)
|
u3m_fault(void* adr_v, c3_i ser_i)
|
||||||
{
|
{
|
||||||
return u3e_fault(adr_v, ser_i);
|
// let the stack overflow handler run.
|
||||||
|
//
|
||||||
|
if ( 0 == ser_i ) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
c3_w* adr_w = (c3_w*)adr_v;
|
||||||
|
u3_post low_p, hig_p;
|
||||||
|
|
||||||
|
if ( (adr_w < u3_Loom) || (adr_w >= (u3_Loom + u3C.wor_i)) ) {
|
||||||
|
fprintf(stderr, "loom: external fault: %p (%p : %p)\r\n\r\n",
|
||||||
|
adr_w, u3_Loom, u3_Loom + u3C.wor_i);
|
||||||
|
c3_assert(0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
_cm_water(&low_p, &hig_p);
|
||||||
|
|
||||||
|
switch ( u3e_fault(low_p, hig_p, u3a_outa(adr_w)) ) {
|
||||||
|
// page tracking invariants violated, fatal
|
||||||
|
//
|
||||||
|
case u3e_flaw_sham: {
|
||||||
|
c3_assert(0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// virtual memory failure (protections), possibly recoverable XX
|
||||||
|
//
|
||||||
|
case u3e_flaw_base: {
|
||||||
|
c3_assert(0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// loom limits exceeded, recoverable
|
||||||
|
//
|
||||||
|
case u3e_flaw_meme: {
|
||||||
|
u3m_signal(c3__meme); // doesn't return
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
case u3e_flaw_good: return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
c3_assert(!"unpossible");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* u3m_save(): update the checkpoint.
|
/* u3m_save(): update the checkpoint.
|
||||||
|
Loading…
Reference in New Issue
Block a user