__declspec(guard(ignore)) void *_CallCatchBlock2( EHRegistrationNode *pRN, // Dynamic info of function with catch FuncInfo *pFuncInfo, // Static info of function with catch void *handlerAddress, // Code address of handler int CatchDepth, // How deeply nested in catch blocks are we? unsigned long NLGCode ) { EHTRACE_ENTER; // // First, create and link in our special guard node: // CatchGuardRN CGRN = { nullptr, (void*)_CatchGuardHandler, __security_cookie ^ (UINT_PTR)&CGRN, pFuncInfo, pRN, CatchDepth + 1 #if defined(ENABLE_EHTRACE) , __ehtrace_level #endif }; __asm { mov eax, FS:[0] // Fetch frame list head mov CGRN.pNext, eax // Link this node in lea eax, CGRN // Put this node at the head mov FS:[0], eax } // // Call the catch // void *continuationAddress = _CallSettingFrame( handlerAddress, pRN, NLGCode ); // // Unlink our registration node // __asm { mov eax, CGRN.pNext // Get parent node mov FS:[0], eax // Put it at the head } EHTRACE_EXIT; return continuationAddress; }
void *CallCatchBlock( EHExceptionRecord *pExcept, EHRegistrationNode *pRN, // Dynamic info of function with catch void *pContext, // ignored DispatcherContext *pDC, // Context within subject frame FuncInfo *pFuncInfo, // Static info of function with catch void *handlerAddress, // Code address of handler int CatchDepth, // How deeply nested in catch blocks are we? unsigned int *pSp ) { FRAMEINFO frameinfo; PFRAMEINFO pframeinfo; EHExceptionRecord *pExceptTmp; unsigned char *pRetAddr; _CreateFrameInfo(&frameinfo, pDC, pContext); frameinfo.pExitContext = (void *)GetSP(); if (pDC->pftinfo == _pftinfo) { // okay we are throw and catch in the same code fragment _pftinfo->pFrameInfo = _pFrameInfoChain; } else { // we are not throw and catch in the same code fragment // we need to chain the _pFrameInfoChain after the pDC->pftinof->pFrameInfo // we should have got all the Frames saved so far, no matter how many code fragments we have been through if (pDC->pftinfo->pFrameInfo != NULL) { // not chain if the case where CRT Is a DLL for everyone if ( pDC->pftinfo->pFrameInfo != _pFrameInfoChain->pNext) { _pFrameInfoChain->pNext = (PFRAMEINFO)(pDC->pftinfo->pFrameInfo); } } } //call the handler pRetAddr = (unsigned char *)_CallSettingFrame(handlerAddress, pRN); *pSp = (unsigned int)GetR4(); //destructing the object if (pExcept && (*(unsigned int *)pExcept != 0xffffffff)) { DestructExceptionObject(pExcept, TRUE, pContext); } if (_pFrameInfoChain) { // don't forget to clear out the frame info the handler we are about // to remove since most if not all off them are stack elements _ASSERTE(_pFrameInfoChain->pftinfo != NULL); _ASSERTE(_pFrameInfoChain->pftinfo->pFrameInfo != NULL); pframeinfo = (PFRAMEINFO)_pFrameInfoChain->pftinfo->pFrameInfo; if (pframeinfo) _pFrameInfoChain->pftinfo->pFrameInfo = pframeinfo->pNext; _pFrameInfoChain = _pFrameInfoChain->pNext; //remove current handler from the chain cNested--; _pftinfo->pFrameInfo = _pFrameInfoChain; } pframeinfo = _pFrameInfoChain; pExceptTmp = pExcept; while (pframeinfo && (pframeinfo->pSp <= (PPMSTACK)pRN)) { // we should destruct any exception objects before this handler's frame if ((EHExceptionRecord *)(pframeinfo->pExcept) != pExceptTmp) { // this is not a re-throw, do destroy DestructExceptionObject((EHExceptionRecord *)pframeinfo->pExcept, TRUE, (void *)pframeinfo->dwRTOC); pExceptTmp = (EHExceptionRecord *)(pframeinfo->pExcept); *(unsigned int *)(pframeinfo->pExcept) = 0xffffffff; pframeinfo->pExcept = NULL; //??? } pframeinfo = pframeinfo->pNext; _pFrameInfoChain = pframeinfo; //remove handler frame from the list cNested--; _pftinfo->pFrameInfo = _pFrameInfoChain; } return (void *)pRetAddr; }