diff options
Diffstat (limited to 'src/vm/eetwain.cpp')
-rw-r--r-- | src/vm/eetwain.cpp | 209 |
1 files changed, 125 insertions, 84 deletions
diff --git a/src/vm/eetwain.cpp b/src/vm/eetwain.cpp index 032bda7c96..2ce7b59578 100644 --- a/src/vm/eetwain.cpp +++ b/src/vm/eetwain.cpp @@ -142,13 +142,15 @@ __forceinline int decodeSigned(PTR_CBYTE& src) /***************************************************************************** * - * Decodes the methodInfoPtr and returns the decoded information - * in the hdrInfo struct. The EIP parameter is the PC location - * within the active method. + * Decodes the X86 GcInfo header and returns the decoded information + * in the hdrInfo struct. + * curOffset is the code offset within the active method used in the + * computation of PrologOffs/EpilogOffs. + * Returns the size of the header (number of bytes decoded). */ -static size_t crackMethodInfoHdr(PTR_VOID methodInfoPtr, - unsigned curOffset, - hdrInfo * infoPtr) +static size_t DecodeGCHdrInfo(GCInfoToken gcInfoToken, + unsigned curOffset, + hdrInfo * infoPtr) { CONTRACTL { NOTHROW; @@ -157,7 +159,7 @@ static size_t crackMethodInfoHdr(PTR_VOID methodInfoPtr, SUPPORTS_DAC; } CONTRACTL_END; - PTR_CBYTE table = PTR_CBYTE(methodInfoPtr); + PTR_CBYTE table = (PTR_CBYTE) gcInfoToken.Info; #if VERIFY_GC_TABLES _ASSERTE(*castto(table, unsigned short *)++ == 0xFEEF); #endif @@ -170,7 +172,7 @@ static size_t crackMethodInfoHdr(PTR_VOID methodInfoPtr, /* Decode the InfoHdr */ InfoHdr header; - table = decodeHeader(table, &header); + table = decodeHeader(table, gcInfoToken.Version, &header); BOOL hasArgTabOffset = FALSE; if (header.untrackedCnt == HAS_UNTRACKED) @@ -199,6 +201,10 @@ static size_t crackMethodInfoHdr(PTR_VOID methodInfoPtr, _ASSERTE(header.syncStartOffset < header.syncEndOffset); } + if (header.revPInvokeOffset == HAS_REV_PINVOKE_FRAME_OFFSET) + { + header.revPInvokeOffset = fastDecodeUnsigned(table); + } /* Some sanity checks on header */ @@ -220,6 +226,7 @@ static size_t crackMethodInfoHdr(PTR_VOID methodInfoPtr, infoPtr->argSize = header.argCount * 4; infoPtr->ebpFrame = header.ebpFrame; infoPtr->interruptible = header.interruptible; + infoPtr->returnKind = (ReturnKind) header.returnKind; infoPtr->prologSize = header.prologSize; infoPtr->epilogSize = header.epilogSize; @@ -232,6 +239,7 @@ static size_t crackMethodInfoHdr(PTR_VOID methodInfoPtr, infoPtr->syncStartOffset = header.syncStartOffset; infoPtr->syncEndOffset = header.syncEndOffset; + infoPtr->revPInvokeOffset = header.revPInvokeOffset; infoPtr->doubleAlign = header.doubleAlign; infoPtr->securityCheck = header.security; @@ -352,7 +360,7 @@ static size_t crackMethodInfoHdr(PTR_VOID methodInfoPtr, (infoPtr->gsCookieOffset < infoPtr->stackSize) && ((header.gsCookieOffset % sizeof(void*)) == 0)); - return table - PTR_CBYTE(methodInfoPtr); + return table - PTR_CBYTE(gcInfoToken.Info); } /*****************************************************************************/ @@ -715,7 +723,7 @@ void EECodeManager::FixContext( ContextType ctxType, /* Extract the necessary information from the info block header */ - stateBuf->hdrInfoSize = (DWORD)crackMethodInfoHdr(pCodeInfo->GetGCInfo(), + stateBuf->hdrInfoSize = (DWORD)DecodeGCHdrInfo(pCodeInfo->GetGCInfoToken(), dwRelOffset, &stateBuf->hdrInfoBody); pState->dwIsSet = 1; @@ -836,11 +844,11 @@ HRESULT EECodeManager::FixContextForEnC(PCONTEXT pCtx, hdrInfo oldInfo, newInfo; - crackMethodInfoHdr(pOldCodeInfo->GetGCInfo(), + DecodeGCHdrInfo(pOldCodeInfo->GetGCInfoToken(), pOldCodeInfo->GetRelOffset(), &oldInfo); - crackMethodInfoHdr(pNewCodeInfo->GetGCInfo(), + DecodeGCHdrInfo(pNewCodeInfo->GetGCInfoToken(), pNewCodeInfo->GetRelOffset(), &newInfo); @@ -1545,7 +1553,7 @@ bool EECodeManager::IsGcSafe( EECodeInfo *pCodeInfo, /* Extract the necessary information from the info block header */ - table = (BYTE *)crackMethodInfoHdr(pCodeInfo->GetGCInfo(), + table = (BYTE *)DecodeGCHdrInfo(pCodeInfo->GetGCInfoToken(), dwRelOffset, &info); @@ -3905,8 +3913,9 @@ bool EECodeManager::UnwindStackFrame(PREGDISPLAY pContext, PTR_CBYTE methodStart = PTR_CBYTE(pCodeInfo->GetSavedMethodCode()); - PTR_VOID methodInfoPtr = pCodeInfo->GetGCInfo(); - DWORD curOffs = pCodeInfo->GetRelOffset(); + GCInfoToken gcInfoToken = pCodeInfo->GetGCInfoToken(); + PTR_VOID methodInfoPtr = gcInfoToken.Info; + DWORD curOffs = pCodeInfo->GetRelOffset(); _ASSERTE(sizeof(CodeManStateBuf) <= sizeof(pState->stateBuf)); CodeManStateBuf * stateBuf = (CodeManStateBuf*)pState->stateBuf; @@ -3915,7 +3924,7 @@ bool EECodeManager::UnwindStackFrame(PREGDISPLAY pContext, { /* Extract the necessary information from the info block header */ - stateBuf->hdrInfoSize = (DWORD)crackMethodInfoHdr(methodInfoPtr, + stateBuf->hdrInfoSize = (DWORD)DecodeGCHdrInfo(gcInfoToken, curOffs, &stateBuf->hdrInfoBody); } @@ -4097,7 +4106,7 @@ bool EECodeManager::EnumGcRefs( PREGDISPLAY pContext, GC_NOTRIGGER; } CONTRACTL_END; - PTR_VOID methodInfoPtr = pCodeInfo->GetGCInfo(); + GCInfoToken gcInfoToken = pCodeInfo->GetGCInfoToken(); unsigned curOffs = pCodeInfo->GetRelOffset(); unsigned EBP = *pContext->pEbp; @@ -4108,7 +4117,7 @@ bool EECodeManager::EnumGcRefs( PREGDISPLAY pContext, unsigned count; hdrInfo info; - PTR_CBYTE table = PTR_CBYTE(methodInfoPtr); + PTR_CBYTE table = PTR_CBYTE(gcInfoToken.Info); #if 0 printf("EECodeManager::EnumGcRefs - EIP = %08x ESP = %08x offset = %x GC Info is at %08x\n", *pContext->pPC, ESP, curOffs, table); #endif @@ -4116,14 +4125,14 @@ bool EECodeManager::EnumGcRefs( PREGDISPLAY pContext, /* Extract the necessary information from the info block header */ - table += crackMethodInfoHdr(methodInfoPtr, - curOffs, - &info); + table += DecodeGCHdrInfo(gcInfoToken, + curOffs, + &info); _ASSERTE( curOffs <= info.methodSize); #ifdef _DEBUG -// if ((methodInfoPtr == (void*)0x37760d0) && (curOffs == 0x264)) +// if ((gcInfoToken.Info == (void*)0x37760d0) && (curOffs == 0x264)) // __asm int 3; if (trEnumGCRefs) { @@ -4220,11 +4229,11 @@ bool EECodeManager::EnumGcRefs( PREGDISPLAY pContext, /* Extract the necessary information from the info block header */ - table = PTR_CBYTE(methodInfoPtr); + table = PTR_CBYTE(gcInfoToken.Info); - table += crackMethodInfoHdr(methodInfoPtr, - curOffs, - &info); + table += DecodeGCHdrInfo(gcInfoToken, + curOffs, + &info); } } @@ -5030,9 +5039,9 @@ OBJECTREF* EECodeManager::GetAddrOfSecurityObject(CrawlFrame *pCF) CodeManStateBuf * stateBuf = (CodeManStateBuf*)pState->stateBuf; /* Extract the necessary information from the info block header */ - stateBuf->hdrInfoSize = (DWORD)crackMethodInfoHdr(gcInfoToken.Info, // <TODO>truncation</TODO> - relOffset, - &stateBuf->hdrInfoBody); + stateBuf->hdrInfoSize = (DWORD)DecodeGCHdrInfo(gcInfoToken, // <TODO>truncation</TODO> + relOffset, + &stateBuf->hdrInfoBody); pState->dwIsSet = 1; if (stateBuf->hdrInfoBody.securityCheck) @@ -5109,10 +5118,10 @@ OBJECTREF EECodeManager::GetInstance( PREGDISPLAY pContext, } CONTRACTL_END; #ifdef _TARGET_X86_ - PTR_VOID methodInfoPtr = pCodeInfo->GetGCInfo(); - unsigned relOffset = pCodeInfo->GetRelOffset(); + GCInfoToken gcInfoToken = pCodeInfo->GetGCInfoToken(); + unsigned relOffset = pCodeInfo->GetRelOffset(); - PTR_CBYTE table = PTR_CBYTE(methodInfoPtr); + PTR_CBYTE table = PTR_CBYTE(gcInfoToken.Info); hdrInfo info; unsigned stackDepth; TADDR taArgBase; @@ -5120,9 +5129,9 @@ OBJECTREF EECodeManager::GetInstance( PREGDISPLAY pContext, /* Extract the necessary information from the info block header */ - table += crackMethodInfoHdr(methodInfoPtr, - relOffset, - &info); + table += DecodeGCHdrInfo(gcInfoToken, + relOffset, + &info); // We do not have accurate information in the prolog or the epilog if (info.prologOffs != hdrInfo::NOT_IN_PROLOG || @@ -5236,14 +5245,15 @@ GenericParamContextType EECodeManager::GetParamContextType(PREGDISPLAY pCont #ifdef _TARGET_X86_ /* Extract the necessary information from the info block header */ - PTR_VOID methodInfoPtr = pCodeInfo->GetGCInfo(); - unsigned relOffset = pCodeInfo->GetRelOffset(); + GCInfoToken gcInfoToken = pCodeInfo->GetGCInfoToken(); + PTR_VOID methodInfoPtr = pCodeInfo->GetGCInfo(); + unsigned relOffset = pCodeInfo->GetRelOffset(); hdrInfo info; - PTR_CBYTE table = PTR_CBYTE(methodInfoPtr); - table += crackMethodInfoHdr(methodInfoPtr, - relOffset, - &info); + PTR_CBYTE table = PTR_CBYTE(gcInfoToken.Info); + table += DecodeGCHdrInfo(gcInfoToken, + relOffset, + &info); if (!info.genericsContext || info.prologOffs != hdrInfo::NOT_IN_PROLOG || @@ -5300,15 +5310,16 @@ PTR_VOID EECodeManager::GetParamTypeArg(PREGDISPLAY pContext, LIMITED_METHOD_DAC_CONTRACT; #ifdef _TARGET_X86_ - PTR_VOID methodInfoPtr = pCodeInfo->GetGCInfo(); - unsigned relOffset = pCodeInfo->GetRelOffset(); + GCInfoToken gcInfoToken = pCodeInfo->GetGCInfoToken(); + PTR_VOID methodInfoPtr = pCodeInfo->GetGCInfo(); + unsigned relOffset = pCodeInfo->GetRelOffset(); /* Extract the necessary information from the info block header */ hdrInfo info; - PTR_CBYTE table = PTR_CBYTE(methodInfoPtr); - table += crackMethodInfoHdr(methodInfoPtr, - relOffset, - &info); + PTR_CBYTE table = PTR_CBYTE(gcInfoToken.Info); + table += DecodeGCHdrInfo(gcInfoToken, + relOffset, + &info); if (!info.genericsContext || info.prologOffs != hdrInfo::NOT_IN_PROLOG || @@ -5424,9 +5435,9 @@ void * EECodeManager::GetGSCookieAddr(PREGDISPLAY pContext, /* Extract the necessary information from the info block header */ hdrInfo * info = &stateBuf->hdrInfoBody; - stateBuf->hdrInfoSize = (DWORD)crackMethodInfoHdr(gcInfoToken.Info, // <TODO>truncation</TODO> - relOffset, - info); + stateBuf->hdrInfoSize = (DWORD)DecodeGCHdrInfo(gcInfoToken, // <TODO>truncation</TODO> + relOffset, + info); pState->dwIsSet = 1; @@ -5482,9 +5493,9 @@ void * EECodeManager::GetGSCookieAddr(PREGDISPLAY pContext, * * Returns true if the given IP is in the given method's prolog or epilog. */ -bool EECodeManager::IsInPrologOrEpilog(DWORD relPCoffset, - PTR_VOID methodInfoPtr, - size_t* prologSize) +bool EECodeManager::IsInPrologOrEpilog(DWORD relPCoffset, + GCInfoToken gcInfoToken, + size_t* prologSize) { CONTRACTL { NOTHROW; @@ -5494,7 +5505,7 @@ bool EECodeManager::IsInPrologOrEpilog(DWORD relPCoffset, #ifndef USE_GC_INFO_DECODER hdrInfo info; - crackMethodInfoHdr(methodInfoPtr, relPCoffset, &info); + DecodeGCHdrInfo(gcInfoToken, relPCoffset, &info); if (prologSize) *prologSize = info.prologSize; @@ -5511,10 +5522,9 @@ bool EECodeManager::IsInPrologOrEpilog(DWORD relPCoffset, * * Returns true if the given IP is in the synchronized region of the method (valid for synchronized functions only) */ -bool EECodeManager::IsInSynchronizedRegion( - DWORD relOffset, - PTR_VOID methodInfoPtr, - unsigned flags) +bool EECodeManager::IsInSynchronizedRegion(DWORD relOffset, + GCInfoToken gcInfoToken, + unsigned flags) { CONTRACTL { NOTHROW; @@ -5524,7 +5534,7 @@ bool EECodeManager::IsInSynchronizedRegion( #ifndef USE_GC_INFO_DECODER hdrInfo info; - crackMethodInfoHdr(methodInfoPtr, relOffset, &info); + DecodeGCHdrInfo(gcInfoToken, relOffset, &info); // We should be called only for synchronized methods _ASSERTE(info.syncStartOffset != INVALID_SYNC_OFFSET && info.syncEndOffset != INVALID_SYNC_OFFSET); @@ -5558,9 +5568,8 @@ size_t EECodeManager::GetFunctionSize(GCInfoToken gcInfoToken) #if defined(_TARGET_X86_) hdrInfo info; - PTR_VOID methodInfoPtr = gcInfoToken.Info; - crackMethodInfoHdr(methodInfoPtr, 0, &info); + DecodeGCHdrInfo(gcInfoToken, 0, &info); return info.methodSize; #elif defined(USE_GC_INFO_DECODER) @@ -5578,15 +5587,47 @@ size_t EECodeManager::GetFunctionSize(GCInfoToken gcInfoToken) PORTABILITY_ASSERT("EECodeManager::GetFunctionSize is not implemented on this platform."); return 0; #endif +} +/***************************************************************************** +* +* Returns the size of a given function. +*/ +ReturnKind EECodeManager::GetReturnKind(GCInfoToken gcInfoToken) +{ + CONTRACTL{ + NOTHROW; + GC_NOTRIGGER; + SUPPORTS_DAC; + } CONTRACTL_END; + if (!gcInfoToken.IsReturnKindAvailable()) + { + return RT_Illegal; + } + +#if defined(_TARGET_X86_) + hdrInfo info; + + DecodeGCHdrInfo(gcInfoToken, 0, &info); + + return info.returnKind; +#elif defined(USE_GC_INFO_DECODER) + + GcInfoDecoder gcInfoDecoder(gcInfoToken, DECODE_RETURN_KIND); + return gcInfoDecoder.GetReturnKind(); + +#else // !_TARGET_X86_ && !USE_GC_INFO_DECODER + PORTABILITY_ASSERT("EECodeManager::GetReturnKind is not implemented on this platform."); + return 0; +#endif } /***************************************************************************** * * Returns the size of the frame of the given function. */ -unsigned int EECodeManager::GetFrameSize(PTR_VOID methodInfoPtr) +unsigned int EECodeManager::GetFrameSize(GCInfoToken gcInfoToken) { CONTRACTL { NOTHROW; @@ -5596,7 +5637,7 @@ unsigned int EECodeManager::GetFrameSize(PTR_VOID methodInfoPtr) #ifndef USE_GC_INFO_DECODER hdrInfo info; - crackMethodInfoHdr(methodInfoPtr, 0, &info); + DecodeGCHdrInfo(gcInfoToken, 0, &info); // currently only used by E&C callers need to know about doubleAlign // in all likelyhood @@ -5624,10 +5665,10 @@ const BYTE* EECodeManager::GetFinallyReturnAddr(PREGDISPLAY pReg) #endif } -BOOL EECodeManager::IsInFilter(void *methodInfoPtr, - unsigned offset, - PCONTEXT pCtx, - DWORD curNestLevel) +BOOL EECodeManager::IsInFilter(GCInfoToken gcInfoToken, + unsigned offset, + PCONTEXT pCtx, + DWORD curNestLevel) { CONTRACTL { NOTHROW; @@ -5640,9 +5681,9 @@ BOOL EECodeManager::IsInFilter(void *methodInfoPtr, hdrInfo info; - crackMethodInfoHdr(methodInfoPtr, - offset, - &info); + DecodeGCHdrInfo(gcInfoToken, + offset, + &info); /* make sure that we have an ebp stack frame */ @@ -5668,7 +5709,7 @@ BOOL EECodeManager::IsInFilter(void *methodInfoPtr, } -BOOL EECodeManager::LeaveFinally(void *methodInfoPtr, +BOOL EECodeManager::LeaveFinally(GCInfoToken gcInfoToken, unsigned offset, PCONTEXT pCtx) { @@ -5681,9 +5722,9 @@ BOOL EECodeManager::LeaveFinally(void *methodInfoPtr, hdrInfo info; - crackMethodInfoHdr(methodInfoPtr, - offset, - &info); + DecodeGCHdrInfo(gcInfoToken, + offset, + &info); DWORD nestingLevel; GetHandlerFrameInfo(&info, pCtx->Ebp, pCtx->Esp, (DWORD) IGNORE_VAL, NULL, &nestingLevel); @@ -5707,7 +5748,7 @@ BOOL EECodeManager::LeaveFinally(void *methodInfoPtr, #endif } -void EECodeManager::LeaveCatch(void *methodInfoPtr, +void EECodeManager::LeaveCatch(GCInfoToken gcInfoToken, unsigned offset, PCONTEXT pCtx) { @@ -5724,7 +5765,7 @@ void EECodeManager::LeaveCatch(void *methodInfoPtr, bool hasInnerFilter; hdrInfo info; - crackMethodInfoHdr(methodInfoPtr, offset, &info); + DecodeGCHdrInfo(gcInfoToken, offset, &info); GetHandlerFrameInfo(&info, pCtx->Ebp, pCtx->Esp, (DWORD) IGNORE_VAL, &baseSP, &nestingLevel, &hasInnerFilter); // _ASSERTE(frameType == FR_HANDLER); @@ -5774,17 +5815,17 @@ TADDR EECodeManager::GetAmbientSP(PREGDISPLAY pContext, } CONTRACTL_END; #ifdef _TARGET_X86_ - PTR_VOID methodInfoPtr = pCodeInfo->GetGCInfo(); + GCInfoToken gcInfoToken = pCodeInfo->GetGCInfoToken(); _ASSERTE(sizeof(CodeManStateBuf) <= sizeof(pState->stateBuf)); CodeManStateBuf * stateBuf = (CodeManStateBuf*)pState->stateBuf; - PTR_CBYTE table = PTR_CBYTE(methodInfoPtr); + PTR_CBYTE table = PTR_CBYTE(gcInfoToken.Info); /* Extract the necessary information from the info block header */ - stateBuf->hdrInfoSize = (DWORD)crackMethodInfoHdr(methodInfoPtr, - dwRelOffset, - &stateBuf->hdrInfoBody); + stateBuf->hdrInfoSize = (DWORD)DecodeGCHdrInfo(gcInfoToken, + dwRelOffset, + &stateBuf->hdrInfoBody); table += stateBuf->hdrInfoSize; pState->dwIsSet = 1; @@ -5868,8 +5909,8 @@ ULONG32 EECodeManager::GetStackParameterSize(EECodeInfo * pCodeInfo) } CONTRACTL_END; #if defined(_TARGET_X86_) - PTR_VOID methodInfoPtr = pCodeInfo->GetGCInfo(); - unsigned dwOffset = pCodeInfo->GetRelOffset(); + GCInfoToken gcInfoToken = pCodeInfo->GetGCInfoToken(); + unsigned dwOffset = pCodeInfo->GetRelOffset(); CodeManState state; state.dwIsSet = 0; @@ -5878,7 +5919,7 @@ ULONG32 EECodeManager::GetStackParameterSize(EECodeInfo * pCodeInfo) CodeManStateBuf * pStateBuf = reinterpret_cast<CodeManStateBuf *>(state.stateBuf); hdrInfo * pHdrInfo = &(pStateBuf->hdrInfoBody); - pStateBuf->hdrInfoSize = (DWORD)crackMethodInfoHdr(methodInfoPtr, dwOffset, pHdrInfo); + pStateBuf->hdrInfoSize = (DWORD)DecodeGCHdrInfo(gcInfoToken, dwOffset, pHdrInfo); // We need to subtract 4 here because ESPIncrOnReturn() includes the stack slot containing the return // address. |