예제 #1
0
__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;
    }
예제 #2
0
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;
}