static int isWatcomHandler // FIGURE OUT IF WATCOM HANDLER ( __EXC_INFO* info ) // - exception info { int retn; if( info->in_func && 0 != info->dctx.pdata ) { unsigned* hand = (unsigned*)info->dctx.pdata->exc; if( 0 != hand && hand[1] == 0x2B544157 // "WAT+" && hand[2] == 0x4D4F432B ) { // "+COM" #if 1 if( procSetsFP( info->dctx.pdata ) ) { info->dctx.fp_actual = GetCtxReg( &info->ctx, Fp ); } else { info->dctx.fp_actual = GetCtxReg( &info->ctx, Sp ); } #else info->dctx.sp_actual = GetCtxReg( &info->ctx, Sp ); info->dctx.fp_actual = GetCtxReg( &info->ctx, Fp ); #endif info->dctx.fp_alternate = info->dctx.fp_actual; getProcInfo( info, &info->dctx ); retn = 1; } else { retn = 0; } } else { retn = 0; } return retn; }
static bool isWatcomHandler // FIGURE OUT IF WATCOM HANDLER ( __EXC_INFO* info ) // - exception info { bool retn; retn = false; if( info->in_func && 0 != info->dctx.pdata ) { unsigned* handler = (unsigned*)info->dctx.pdata->ExceptionHandler; if( NULL != handler && handler[1] == 0x2B544157 // "WAT+" && handler[2] == 0x4D4F432B ) { // "+COM" #if 1 if( procSetsFP( info->dctx.pdata ) ) { info->dctx.fp_actual = GetCtxReg( &info->ctx, Fp ); } else { info->dctx.fp_actual = GetCtxReg( &info->ctx, Sp ); } #else info->dctx.sp_actual = GetCtxReg( &info->ctx, Sp ); info->dctx.fp_actual = GetCtxReg( &info->ctx, Fp ); #endif info->dctx.fp_alternate = info->dctx.fp_actual; getProcInfo( info, &info->dctx ); retn = true; } } return( retn ); }
static void* getProcFrame // GET PROCEDURE FRAME ( PData* pdata // - procedure descriptor , PD_DISP_CTX* dctx ) // - dispatch context { void* frame; // - frame ptr. #if 0 if( procSetsFP( pdata ) ) { frame = (void*)dctx->fp_actual; } else { frame = (void*)dctx->sp_actual; } #else if( dctx->pdata != pdata ) { GOOF_EXC( "getProcFram: dctx->pdata != pdata" ); } // AFS: this function seems to change a lot and it very brittle; // is it possible to use 'sp' from the handler? frame = dctx->fp_alternate; #endif return frame; }
void CPPLIB( PdUnwind ) // UNWIND USING PROCEDURE DESCRIPTORS ( FsExcRec* exc_rec ) // - exception record { DISPATCH_EXC* dispatch; // - dispatch control RW_DTREG* rw; // - R/W block being dispatched void* frame; // - frame for rtn. (SP or FP) void* pc; // - PC for continuation (after the setjmp) _CONTEXT ctx; // - context for function unsigned save_area[3*2]; // - save area RtlCaptureContext( &ctx ); pc = CPPLIB( PdCtx )( &ctx, save_area ); if( pc ) { dispatch = exc_rec->dispatch; rw = dispatch->rw; frame = (void*)( (char*)rw - rw->base.ro->fun.rw_offset ); if( procSetsFP( dispatch->pdata ) ) { RtlUnwindRfp( frame, pc, exc_rec, save_area ); } else { RtlUnwind( frame, pc, exc_rec, save_area ); } } }