Пример #1
0
CNktDvDbObjectNoRef::eCallingConvention CNktDvExportedFunction::GetCallingConvention() const
{
  CNktDvDbObjectNoRef *_lpDbObj;

  _lpDbObj = GetFunctionEntry();
  return (_lpDbObj != NULL) ? (lpDbObj->GetFuncCallingConvention()) : CNktDvDbObjectNoRef::ccNA;
}
Пример #2
0
//PowerMac version of stack walking to find a C++ exception handler
//Assume:
//		_pftinfo
//
void MacExceptionDispatch(PEXCEPTION_RECORD pExceptionRecord)
{
	PPMSTACK spCur;				    
	PPMSTACK spCurCatch;				    
	DispatcherContext curDC;
	PRUNTIME_FUNCTION pFunctionEntry;
	PRUNTIME_FUNCTION pFunctionEntryCatch = NULL;
	PFTINFO pftinfoTOC;
	PPMSTACK pFrame;
	unsigned long cNestedTmp;
	PFRAMEINFO pframeinfo;
	
 	spCur = (PMSTACK *)GetSP();

	//Loop through the frames backwards on the stack to find a frame which has an EH handler
	//Assume:
	//      End of Stack: when the save area link register is NULL
	//      .pdata has Exception Handler points to CxxFrameHandler if an EH Frame
	//				   Exception Data points to FuncInfo
	spCur = spCur->pSpBackChain; //this should be in CxxThrowException frame
	spCur = spCur->pSpBackChain; //this should be in caller of CxxThrowException frame

	//Is this a cross TOC call? Do we need to switch RTOC???!!!
	if ( (spCur->dwLNKreg >= _pftinfo->dwEntryCF) && (spCur->dwLNKreg <= ((unsigned long)((char *)_pftinfo->dwEntryCF+ _pftinfo->dwSizeCF))) || spCur->dwTOCreg == (unsigned long)GetRTOC())
		{
		// okay, we are throw in the same code fragment as CRT, CRT being statically linked in, or the same as last throw
		}
	else if ( (spCur->dwLNKreg >= _pftinfoCRT->dwEntryCF) && (spCur->dwLNKreg <= ((unsigned long)((char *)_pftinfoCRT->dwEntryCF+ _pftinfoCRT->dwSizeCF))) || spCur->dwTOCreg == (unsigned long)GetRTOC())
		{
		_pftinfo = _pftinfoCRT;
		}
	else
		{
		// make _pftinfo point to the code fragment which has thrown the exception, CRT must be a DLL now
		_ASSERTE(spCur->dwTOCreg);
		_pftinfo = (PFTINFO)(*(unsigned long *)((char *)spCur->dwTOCreg + OFSFTINFO));
		dwRTOC = spCur->dwTOCreg;
		}


	while (spCur->dwLNKreg)
		{
		if (_pFrameInfoChain)
			{
			// we should only look the outer nested scope for handlers and we should skip catch handler frame
			// because the actual frame called the catch handler is way down
			if ( (spCur > _pFrameInfoChain->pExitContext) && (spCur < _pFrameInfoChain->pSp) )
				{
				spCur = spCur->pSpBackChain;
				continue;
				}

			if (cNested > 0)
				{
				cNestedTmp = cNested;
				pframeinfo = _pFrameInfoChain;
				while (cNestedTmp-- && pframeinfo)
					{
					// This means we are throw in the catch
					if ( (spCur->pSpBackChain == pframeinfo->pExitContext) )
						{
						pFunctionEntryCatch = GetFunctionEntry(spCur, &pftinfoTOC);
						spCurCatch = spCur;
						break;
						}
					pframeinfo = pframeinfo->pNext;
					}
				if (pframeinfo)
					{
					spCur = spCur->pSpBackChain;
					continue;
					}
				}
			}

		pFunctionEntry = GetFunctionEntry(spCur, &pftinfoTOC);

		if (pFunctionEntry && (pFunctionEntry->ExceptionHandler != NULL))
			{
			//stack point, old PC(in linker register, execution point==state), Registers in Context
			pFrame = spCur;
			curDC.ControlPc = spCur->dwLNKreg;
			curDC.FunctionEntry = pFunctionEntry;  
			curDC.EstablisherFrame = spCur;   
            curDC.pExcept = pExceptionRecord;   
			if (_pftinfo != pftinfoTOC)
				{
				// we are calling catch which is in different code fragment
				curDC.pftinfo = pftinfoTOC;   
				curDC.pftinfo->pFrameInfo = _pFrameInfoChain;
				_pftinfo->pFrameInfo = _pFrameInfoChain;
				_pFrameInfoChain = 0;      //reset
				cNested = 0;
				}
			else
				{
				curDC.pftinfo = _pftinfo;
   				curDC.pftinfo->pFrameInfo = _pFrameInfoChain;
				}
			if (dwRTOC == 0)
					{
					dwRTOC = (unsigned long)GetRTOC();  //not CRT as DLL case
					}
			//dwRTOC has throw object RTOC
			//curDC has handler's info
			if (pFunctionEntryCatch == pFunctionEntry)
				{
				// we have to  update the return address in original catch frame
				if (spCurCatch->dwLNKreg > curDC.ControlPc)
					{
					curDC.ControlPc = spCurCatch->dwLNKreg;
					}
				//we have to remeber the current return from catch's throw, so we can unwinding properly.
				//the return in the frame is adjusted to next state, so it can be off for unwinding
				//Note: we only need all the trouble for statically nested case
				curDC.ControlPcOld = spCurCatch->dwLNKreg;
				fStaticNested = 1;
				}
			(*pFunctionEntry->ExceptionHandler)(pExceptionRecord, pFrame, (void *)dwRTOC, &curDC);
			if (_pftinfo != pftinfoTOC)
				{
				_pFrameInfoChain = (PFRAMEINFO)_pftinfo->pFrameInfo; //reset our globals if we come back;STILL problem!!!
				pframeinfo = _pFrameInfoChain;	
				while (pframeinfo)
					{
					// This means we are throw in the catch
					cNested++;
					pframeinfo = pframeinfo->pNext;
					}
				}
			fStaticNested = 0;
			pFuncEntryLast = pFunctionEntry;
			}
		spCur = spCur->pSpBackChain;
		if (dwSPStartup)
			{
			if (spCur->dwLNKreg && (spCur > (PPMSTACK)dwSPStartup))
				{
				//we are at second to last of stack frame, break out the loop
				break;
				}
			}
		else
			{
			// we don't know our bottom of stack, didn't go through this instance of mainCRTStartup
			// let's break out the loop if we encounter 68k frame
			if ((unsigned int)spCur & 0x01)
				{
				break;
				}
			}
		}

	//We don't have a handler, we should just exit out of the program
    terminate();
}
Пример #3
0
void _UnwindNestedFrames(
	EHRegistrationNode	*pFrame,		// Unwind up to (but not including) this frame
	EHExceptionRecord	*pExcept		// The exception that initiated this unwind
	//void				*pContext		// Context info for current exception
) {

	PPMSTACK spCur;
	PPMSTACK spCurCatch;				    
	DispatcherContext curDC;
	PFTINFO pftinfoTOC;
	PRUNTIME_FUNCTION pFunctionEntry;
	PRUNTIME_FUNCTION pFunctionEntryCatch = NULL;
	unsigned long cNestedTmp;
	PFRAMEINFO pframeinfo;

 	spCur = (PPMSTACK)GetSP();

	//Loop through the frames backwards on the stack to destroy objects until target frame
	//Assume:

	spCur = spCur->pSpBackChain;
	while (spCur < pFrame)
		{
		// we should only look the frame which hasn't been looked
		if (_pFrameInfoChain)
			{
			if ((spCur > _pFrameInfoChain->pExitContext) && (spCur < _pFrameInfoChain->pSp))
				{
				spCur = spCur->pSpBackChain;
				continue;
				}

			if (cNested > 0)
				{
				cNestedTmp = cNested;
				pframeinfo = _pFrameInfoChain;
				while (cNestedTmp-- && pframeinfo)
					{
					if ( (spCur->pSpBackChain == pframeinfo->pExitContext) )
						{
						pFunctionEntryCatch = GetFunctionEntry(spCur, &pftinfoTOC);
						spCurCatch = spCur;
						break;
						}
					pframeinfo = pframeinfo->pNext;
					}
				if (pframeinfo)
					{
					spCur = spCur->pSpBackChain;
					continue;
					}
				}

			}
		pFunctionEntry = GetFunctionEntry(spCur, &pftinfoTOC);
		if (pFunctionEntry && pFunctionEntry->ExceptionHandler != NULL)
			{
			//set unwinding flag
			//stack point, old PC(in linker register, execution point==state), Registers in Context
			PER_FLAGS(pExcept) |= EXCEPTION_UNWINDING;
			curDC.ControlPc = spCur->dwLNKreg;
			curDC.FunctionEntry = pFunctionEntry;  //what else to save?!
			curDC.EstablisherFrame = spCur;
			curDC.pftinfo = pftinfoTOC;
			if (pFunctionEntryCatch == pFunctionEntry)
				{
				// we have to  update the return address in original catch frame
				if (spCurCatch->dwLNKreg > curDC.ControlPc)
					{
					curDC.ControlPc = spCurCatch->dwLNKreg;
					}
				}
			(*pFunctionEntry->ExceptionHandler)(pExcept, spCur, NULL, &curDC);
			}
		spCur = spCur->pSpBackChain;
		}	
	//
	// clear the unwinding flag, in case exception is rethown
	//
	PER_FLAGS(pExcept) &= ~EXCEPTION_UNWINDING;
	return;
}