summaryrefslogtreecommitdiff
path: root/src/vm/eetwain.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/vm/eetwain.cpp')
-rw-r--r--src/vm/eetwain.cpp209
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.