Ejemplo n.º 1
0
void FixupInlineGetters(DWORD tlsSlot, const LPVOID * pLocations, int nLocations)
{
    BYTE* pInlineGetter;
    DWORD dwOldProtect;
    for (int i=0; i<nLocations; i++)
    {
        pInlineGetter = (BYTE*)GetEEFuncEntryPoint((BYTE*)pLocations[i]);

        static const DWORD cbPatch = 9;
        if (!ClrVirtualProtect(pInlineGetter, cbPatch, PAGE_EXECUTE_READWRITE, &dwOldProtect))
        {
            ThrowLastError();
        }

        DWORD offset = (tlsSlot * sizeof(LPVOID) + offsetof(TEB, TlsSlots));

#if defined(_TARGET_AMD64_)
        // mov  r??, gs:[TLS offset]
        _ASSERTE_ALL_BUILDS("clr/src/VM/JITinterfaceGen.cpp",
                            pInlineGetter[0] == 0x65 &&
                            pInlineGetter[2] == 0x8B &&
                            pInlineGetter[4] == 0x25 &&
                            "Initialization failure while stomping instructions for the TLS slot offset: the instruction at the given offset did not match what we expect");

        *((DWORD*)(pInlineGetter + 5)) = offset;
#else // _TARGET_AMD64_
        PORTABILITY_ASSERT("FixupInlineGetters");
#endif //_TARGET_AMD64_

        FlushInstructionCache(GetCurrentProcess(), pInlineGetter, cbPatch);
        ClrVirtualProtect(pInlineGetter, cbPatch, dwOldProtect, &dwOldProtect);
    }
}
Ejemplo n.º 2
0
//
// CopyThreadContext does an intelligent copy from c2 to c1,
// respecting the ContextFlags of both contexts.
//
void _CopyThreadContext(CONTEXT *c1, CONTEXT *c2)
{
    DWORD c1Flags = c1->ContextFlags;
    DWORD c2Flags = c2->ContextFlags;
    LOG((LF_CORDB, LL_INFO1000000,
         "CP::CTC: c1=0x%08x c1Flags=0x%x, c2=0x%08x c2Flags=0x%x\n",
         c1, c1Flags, c2, c2Flags));

    #define CopyContextChunk(_t, _f, _e, _c) {\
        LOG((LF_CORDB, LL_INFO1000000, \
             "CP::CTC: copying " #_c  ": 0x%08x <--- 0x%08x (%d)\n", \
             (_t), (_f), ((UINT_PTR)(_e) - (UINT_PTR)_t))); \
        memcpy((_t), (_f), ((UINT_PTR)(_e) - (UINT_PTR)_t)); \
    }

#ifdef _X86_ // Reliance on contexts registers
    
    if ((c1Flags & c2Flags & CONTEXT_CONTROL) == CONTEXT_CONTROL)
        CopyContextChunk(&(c1->Ebp), &(c2->Ebp), c1->ExtendedRegisters,
                         CONTEXT_CONTROL);
    
    if ((c1Flags & c2Flags & CONTEXT_INTEGER) == CONTEXT_INTEGER)
        CopyContextChunk(&(c1->Edi), &(c2->Edi), &(c1->Ebp),
                         CONTEXT_INTEGER);

    
    if ((c1Flags & c2Flags & CONTEXT_FLOATING_POINT) == CONTEXT_FLOATING_POINT)
        CopyContextChunk(&(c1->FloatSave), &(c2->FloatSave),
                         (&c1->FloatSave)+1,
                         CONTEXT_FLOATING_POINT);
    

#elif defined(_PPC_)

    if ((c1Flags & c2Flags & CONTEXT_CONTROL) == CONTEXT_CONTROL)
        CopyContextChunk(&(c1->Msr), &(c2->Msr), &c1->ContextFlags,
                         CONTEXT_CONTROL);
    
    if ((c1Flags & c2Flags & CONTEXT_INTEGER) == CONTEXT_INTEGER)
        CopyContextChunk(&(c1->Gpr0), &(c2->Gpr0), &(c1->Msr),
                         CONTEXT_INTEGER);

    
    if ((c1Flags & c2Flags & CONTEXT_FLOATING_POINT) == CONTEXT_FLOATING_POINT)
        CopyContextChunk(&(c1->Fpr0), &(c2->Fpr0),
                         &(c1->Gpr0),
                         CONTEXT_FLOATING_POINT);
    
    
#else
    PORTABILITY_ASSERT("CopyThreadContext (common.cpp) is not implemented on this platform.");
#endif
}
Ejemplo n.º 3
0
HRESULT STDMETHODCALLTYPE
LiveProcDataTarget::GetMachineType( 
    /* [out] */ ULONG32 *machine)
{
    LEAF_CONTRACT;

#if defined(_X86_)
    *machine = IMAGE_FILE_MACHINE_I386;
#else
    PORTABILITY_ASSERT("Unknown Processor");
#endif
    return S_OK;
}
Ejemplo n.º 4
0
 void RedirectForThrowControl()
 {
     PORTABILITY_ASSERT("Implement for PAL");
 }
Ejemplo n.º 5
0
 void RedirectForThreadAbort()
 {
     PORTABILITY_ASSERT("Implement for PAL");
 }
Ejemplo n.º 6
0
 void VarargPInvokeStub_RetBuffArg()
 {
     PORTABILITY_ASSERT("Implement for PAL");
 }
Ejemplo n.º 7
0
 void VarargPInvokeStub()
 {
     PORTABILITY_ASSERT("Implement for PAL");
 }
Ejemplo n.º 8
0
 void PInvokeStubForHostInner(DWORD dwStackSize, LPVOID pStackFrame, LPVOID pTarget)
 {
     PORTABILITY_ASSERT("Implement for PAL");
 }
Ejemplo n.º 9
0
 void GenericPInvokeCalliHelper()
 {
     PORTABILITY_ASSERT("Implement for PAL");
 }
Ejemplo n.º 10
0
BYTE *GetAddressOfRegisterJit(ICorDebugInfo::RegNum reg, REGDISPLAY *rd)
{
    BYTE *ret = NULL;
#ifdef _X86_
    switch(reg)
    {
        case ICorDebugInfo::REGNUM_EAX:
        {
            ret = *(BYTE**)rd->pEax;
            break;
        }
        case ICorDebugInfo::REGNUM_ECX:
        {
            ret = *(BYTE**)rd->pEcx;
            break;
        }
        case ICorDebugInfo::REGNUM_EDX:
        {
            ret = *(BYTE**)rd->pEdx;
            break;
        }
        case ICorDebugInfo::REGNUM_EBX:
        {
            ret = *(BYTE**)rd->pEbx;
            break;
        }
        case ICorDebugInfo::REGNUM_ESP:
        {
            ret = *(BYTE**)(&(rd->SP));
            break;
        }
        case ICorDebugInfo::REGNUM_EBP:
        {
            ret = *(BYTE**)rd->pEbp;
            break;
        }
        case ICorDebugInfo::REGNUM_ESI:
        {
            ret = *(BYTE**)rd->pEsi;
            break;
        }
        case ICorDebugInfo::REGNUM_EDI:
        {
            ret = *(BYTE**)rd->pEdi;
            break;
        }
        default:
        {
            ret = NULL;
            break;
        }
    }
#elif defined(_PPC_)
    switch(reg)
    {
    case ICorDebugInfo::REGNUM_SP:
        {
            ret = (BYTE*)rd->SP;
            break;
        }
    case ICorDebugInfo::REGNUM_FP:
        {
            ret = *(BYTE**)rd->pR[30-13];
            break;
        }
    // Cases for any other registers (REGNUM_R3 .. R10) default
    // REGDISPLAY structure has no info on those
    default:
        {
            ret = NULL;
            break;
        }
    }
#else
    PORTABILITY_ASSERT("GetAddressOfRegisterJit (Thread.cpp) is not implemented on this platform.");
#endif
    
    return ret;
}
Ejemplo n.º 11
0
//
// Callback for walking a thread's stack. Sends required frame data to the
// DI as send buffers fill up.
//
StackWalkAction DebuggerThread::TraceAndSendStackCallback(FrameInfo *pInfo, VOID* data)
{
    _RefreshStackFramesData *rsfd = (_RefreshStackFramesData*) data;
    Thread *t = rsfd->thread;
    DebuggerIPCEvent *pEvent = NULL;

    if (rsfd->iWhich == IPC_TARGET_INPROC)
    {
        pEvent = rsfd->pEvent;
    }
    else
    {
        _ASSERTE( rsfd->iWhich == IPC_TARGET_OUTOFPROC );
        pEvent = rsfd->rcThread->GetIPCEventSendBuffer(rsfd->iWhich);
    }

    // Record registers for the start of the next chain, if appropriate.
    if (rsfd->needChainRegisters)
    {
        rsfd->chainRegisters = pInfo->registers;
        rsfd->needChainRegisters = false;
    }

    // Only report frames which are chain boundaries, or are not marked internal.
    LOG((LF_CORDB, LL_INFO1000, "DT::TASSC:chainReason:0x%x internal:0x%x  "
         "md:0x%x **************************\n", pInfo->chainReason,
         pInfo->internal, pInfo->md));

    if (pInfo->chainReason == 0 && (pInfo->internal || pInfo->md == NULL))
        return SWA_CONTINUE;

#ifdef LOGGING
    if( pInfo->quickUnwind == true )
        LOG((LF_CORDB, LL_INFO10000, "DT::TASSC: rsfd => Doing quick unwind\n"));
#endif
    
    //
    // If we've filled this event, send it off to the Right Side
    // before continuing the walk.
    //
    if ((rsfd->eventSize + sizeof(DebuggerIPCE_STRData)) >= rsfd->eventMaxSize)
    {
        //
        //
        pEvent->StackTraceResultData.threadUserState = g_pEEInterface->GetUserState(t);
        
        if (rsfd->iWhich == IPC_TARGET_OUTOFPROC)            
        {
            rsfd->rcThread->SendIPCEvent(rsfd->iWhich);
        }
        else
        {
            DebuggerIPCEvent *peT;
            peT = rsfd->rcThread->GetIPCEventSendBufferContinuation(pEvent);

            if (peT == NULL)
            {
                pEvent->hr = E_OUTOFMEMORY;
                return SWA_ABORT;
            }
            
            CopyEventInfo(pEvent, peT);
            pEvent = peT;
            rsfd->pEvent = peT;
            rsfd->eventSize = 0;
        }
        //
        // Reset for the next set of frames.
        //
        pEvent->StackTraceResultData.traceCount = 0;
        rsfd->currentSTRData = &(pEvent->StackTraceResultData.traceData);
        rsfd->eventSize = (UINT_PTR)(rsfd->currentSTRData) - (UINT_PTR)(pEvent);
    }

    MethodDesc* fd = pInfo->md;
    
    if (fd != NULL && !pInfo->internal)
    {
        //
        // Send a frame
        //

        rsfd->currentSTRData->isChain = false;
        rsfd->currentSTRData->fp = pInfo->fp;
        rsfd->currentSTRData->quicklyUnwound = pInfo->quickUnwind;

        // Pass the appdomain that this thread was in when it was executing this frame to the Right Side.
        rsfd->currentSTRData->currentAppDomainToken = (void*)pInfo->currentAppDomain;

        REGDISPLAY* rd = &pInfo->registers;
        DebuggerREGDISPLAY* drd = &(rsfd->currentSTRData->rd);
        LPVOID FPAddress = GetRegdisplayFPAddress(rd);

        // Set some common elements
        drd->SP  = rd->SP;
        drd->PC   = (SIZE_T)*(rd->pPC);
        drd->FP  = (FPAddress == NULL ? 0 : *((SIZE_T *)FPAddress));

        //
        // PUSHED_REG_ADDR gives us NULL if the register still lives in the thread's context, or it gives us the address
        // of where the register was pushed for this frame.
        //
#define PUSHED_REG_ADDR(_a) (((UINT_PTR)(_a) >= (UINT_PTR)rd->pContext) && ((UINT_PTR)(_a) <= ((UINT_PTR)rd->pContext + sizeof(CONTEXT)))) ? NULL : (_a)

        // Frame pointer        
        drd->pFP = PUSHED_REG_ADDR(FPAddress);

#ifdef _X86_

        drd->pEdi = PUSHED_REG_ADDR(rd->pEdi);
        drd->Edi  = (rd->pEdi == NULL ? 0 : *(rd->pEdi));
        drd->pEsi = PUSHED_REG_ADDR(rd->pEsi);
        drd->Esi  = (rd->pEsi == NULL ? 0 : *(rd->pEsi));
        drd->pEbx = PUSHED_REG_ADDR(rd->pEbx);
        drd->Ebx  = (rd->pEbx == NULL ? 0 : *(rd->pEbx));
        drd->pEdx = PUSHED_REG_ADDR(rd->pEdx);
        drd->Edx  = (rd->pEdx == NULL ? 0 : *(rd->pEdx));
        drd->pEcx = PUSHED_REG_ADDR(rd->pEcx);
        drd->Ecx  = (rd->pEcx == NULL ? 0 : *(rd->pEcx));
        drd->pEax = PUSHED_REG_ADDR(rd->pEax);
        drd->Eax  = (rd->pEax == NULL ? 0 : *(rd->pEax));
        
        // Please leave EBP, ESP, EIP at the front so I don't have to scroll
        // left to see the most important registers.  Thanks!
        LOG( (LF_CORDB, LL_INFO1000, "DT::TASSC:Registers:"
            "Ebp = %x   Esp = %x   Eip = %x   Edi:%d   "
            "Esi = %x   Ebx = %x   Edx = %x   Ecx = %x   Eax = %x\n",
            drd->FP, drd->SP, drd->PC, drd->Edi,
            drd->Esi, drd->Ebx, drd->Edx, drd->Ecx, drd->Eax ) );
#elif defined(_PPC_) || defined (_SPARC_)
        // All that's needed for now
#else
        PORTABILITY_ASSERT("TraceAndSendStackCallback needs some munging for this platform.");
#endif
            
        DebuggerIPCE_FuncData* currentFuncData = &rsfd->currentSTRData->v.funcData;
        _ASSERTE(fd != NULL);

        GetVAInfo(&(currentFuncData->fVarArgs),
                  &(currentFuncData->rpSig),
                  &(currentFuncData->cbSig),
                  &(currentFuncData->rpFirstArg),
                  fd,
                  rd,
                  pInfo->relOffset);


        LOG((LF_CORDB, LL_INFO10000, "DT::TASSC: good frame for %s::%s\n",
             fd->m_pszDebugClassName,
             fd->m_pszDebugMethodName));

        //
        // Fill in information about the function that goes with this
        // frame.
        //
        currentFuncData->funcRVA = g_pEEInterface->MethodDescGetRVA(fd);
        _ASSERTE (t != NULL);
        
        Module *pRuntimeModule = g_pEEInterface->MethodDescGetModule(fd);
        AppDomain *pAppDomain = pInfo->currentAppDomain;
        currentFuncData->funcDebuggerModuleToken = (void*) g_pDebugger->LookupModule(pRuntimeModule, pAppDomain);
        
        if (currentFuncData->funcDebuggerModuleToken == NULL && rsfd->iWhich == IPC_TARGET_INPROC)
        {
            currentFuncData->funcDebuggerModuleToken = (void*)g_pDebugger->AddDebuggerModule(pRuntimeModule, pAppDomain);
            
            LOG((LF_CORDB, LL_INFO100, "DT::TASSC: load module Mod:%#08x AD:%#08x isDynamic:%#x runtimeMod:%#08x\n",
                 currentFuncData->funcDebuggerModuleToken, pAppDomain, pRuntimeModule->IsReflection(), pRuntimeModule));
        }                                   
        _ASSERTE(currentFuncData->funcDebuggerModuleToken != 0);
        
        currentFuncData->funcDebuggerAssemblyToken = 
            (g_pEEInterface->MethodDescGetModule(fd))->GetClassLoader()->GetAssembly();
        currentFuncData->funcMetadataToken = fd->GetMemberDef();

        currentFuncData->classMetadataToken = fd->GetClass()->GetCl();

        // Pass back the local var signature token.
        COR_ILMETHOD *CorILM = g_pEEInterface->MethodDescGetILHeader(fd);

        if (CorILM == NULL )
        {
            currentFuncData->localVarSigToken = mdSignatureNil;
            currentFuncData->ilStartAddress = NULL;
            currentFuncData->ilSize = 0;
            rsfd->currentSTRData->v.ILIP = NULL;

            currentFuncData->nativeStartAddressPtr = NULL;
            currentFuncData->nativeSize = 0;
            currentFuncData->nativenVersion = DebuggerJitInfo::DJI_VERSION_FIRST_VALID;
        }
        else
        {
            COR_ILMETHOD_DECODER ILHeader(CorILM);

            if (ILHeader.GetLocalVarSigTok() != 0)
                currentFuncData->localVarSigToken = ILHeader.GetLocalVarSigTok();
            else
                currentFuncData->localVarSigToken = mdSignatureNil; 
            //
            //
            currentFuncData->ilStartAddress = const_cast<BYTE*>(ILHeader.Code);
            currentFuncData->ilSize = ILHeader.GetCodeSize();

            currentFuncData->ilnVersion = g_pDebugger->GetVersionNumber(fd);

            LOG((LF_CORDB,LL_INFO10000,"Sending il Ver:0x%x in stack trace!\n", currentFuncData->ilnVersion));

            DebuggerJitInfo *jitInfo = g_pDebugger->GetJitInfo(fd, (const BYTE*)*pInfo->registers.pPC);

            if (jitInfo == NULL)
            {
                //EnC: Couldn't find the code;
                rsfd->currentSTRData->v.ILIP = NULL;

                // Note: always send back the size of the method. This
                // allows us to get the code, even when we haven't
                // been tracking. (Handling of the GetCode message
                // knows how to find the start address of the code, or
                // how to respond if is been pitched.)
                currentFuncData->nativeSize = g_pEEInterface->GetFunctionSize(fd);

                currentFuncData->nativeStartAddressPtr = NULL;
                currentFuncData->nativenVersion = DebuggerJitInfo::DJI_VERSION_FIRST_VALID;
                currentFuncData->CodeVersionToken = NULL;
                currentFuncData->ilToNativeMapAddr = NULL;
                currentFuncData->ilToNativeMapSize = 0;
                currentFuncData->nVersionMostRecentEnC = currentFuncData->ilnVersion;
            }
            else
            {
                LOG((LF_CORDB,LL_INFO10000,"DeTh::TASSC: Code: 0x%x Got DJI "
                     "0x%x, from 0x%x to 0x%x\n",(const BYTE*)drd->PC,jitInfo, 
                     jitInfo->m_addrOfCode, jitInfo->m_addrOfCode + 
                     jitInfo->m_sizeOfCode));
                
                DWORD whichIrrelevant;
                rsfd->currentSTRData->v.ILIP = const_cast<BYTE*>(ILHeader.Code) 
                    + jitInfo->MapNativeOffsetToIL((SIZE_T)pInfo->relOffset,
                                                   &rsfd->currentSTRData->v.mapping,
                                                   &whichIrrelevant);

                // Pass back the pointers to the sequence point map so
                // that the RIght Side can copy it out if needed.
                _ASSERTE(jitInfo->m_sequenceMapSorted);
                
                currentFuncData->ilToNativeMapAddr = jitInfo->m_sequenceMap;
                currentFuncData->ilToNativeMapSize = jitInfo->m_sequenceMapCount;
                
                if (!jitInfo->m_codePitched)
                {   // It's there & life is groovy
                    currentFuncData->nativeStartAddressPtr = &(jitInfo->m_addrOfCode);
                    currentFuncData->nativeSize = g_pEEInterface->GetFunctionSize(fd);
                    currentFuncData->nativenVersion = jitInfo->m_nVersion;
                    currentFuncData->CodeVersionToken = (void *)jitInfo;
                }
                else
                {
                    // It's been pitched
                    currentFuncData->nativeStartAddressPtr = NULL;
                    currentFuncData->nativeSize = 0;
                }
                
                LOG((LF_CORDB,LL_INFO10000,"Sending native Ver:0x%x Tok:0x%x in stack trace!\n",
                     currentFuncData->nativenVersion,currentFuncData->CodeVersionToken));
            }
        }

        currentFuncData->nativeOffset = (SIZE_T)pInfo->relOffset;

        //
        // Bump our pointers to the next space for the next frame.
        //
        pEvent->StackTraceResultData.traceCount++;
        rsfd->currentSTRData++;
        rsfd->eventSize += sizeof(DebuggerIPCE_STRData);
    }

    if (pInfo->chainReason != 0)
    {
        //
        // If we've filled this event, send it off to the Right Side
        // before continuing the walk.
        //
        if ((rsfd->eventSize + sizeof(DebuggerIPCE_STRData)) >=
            rsfd->eventMaxSize)
        {
            //
            //
            pEvent->StackTraceResultData.threadUserState = 
                g_pEEInterface->GetUserState(t);
                
            if (rsfd->iWhich == IPC_TARGET_OUTOFPROC)            
            {
                rsfd->rcThread->SendIPCEvent(rsfd->iWhich);
            }
            else
            {
                DebuggerIPCEvent *peT;
                peT = rsfd->rcThread->GetIPCEventSendBufferContinuation(pEvent);
                
                if (peT == NULL)
                {
                    pEvent->hr = E_OUTOFMEMORY;
                    return SWA_ABORT;
                }
                
                CopyEventInfo(pEvent, peT);                    
                pEvent = peT;
                rsfd->pEvent = peT;
                rsfd->eventSize = 0;
            }

            //
            // Reset for the next set of frames.
            //
            pEvent->StackTraceResultData.traceCount = 0;
            rsfd->currentSTRData = &(pEvent->StackTraceResultData.traceData);
            rsfd->eventSize = (UINT_PTR)(rsfd->currentSTRData) -
                (UINT_PTR)(pEvent);
        }

        //
        // Send a chain boundary
        //

        rsfd->currentSTRData->isChain = true;
        rsfd->currentSTRData->u.chainReason = pInfo->chainReason;
        rsfd->currentSTRData->u.managed = pInfo->managed;
        rsfd->currentSTRData->u.context = pInfo->context;
        rsfd->currentSTRData->fp = pInfo->fp;
        rsfd->currentSTRData->quicklyUnwound = pInfo->quickUnwind;

#ifdef _DEBUG
        REGDISPLAY* rd = &rsfd->chainRegisters;
#endif  // _DEBUG

#ifdef _X86_
        LOG( (LF_CORDB, LL_INFO1000, "DT::TASSC:Registers:  Edi:%d \
  Esi = %x   Ebx = %x   Edx = %x   Ecx = %x   Eax = %x   Ebp = %x\n", (rd->pEdi == NULL ? 0 : *(rd->pEdi)),
              (rd->pEsi == NULL ? 0 : *(rd->pEsi)), (rd->pEbx == NULL ? 0 : *(rd->pEbx)), 
              (rd->pEdx == NULL ? 0 : *(rd->pEdx)), (rd->pEcx == NULL ? 0 : *(rd->pEcx)), 
              (rd->pEax == NULL ? 0 : *(rd->pEax)), (rd->pEbp == NULL ? 0 : *(rd->pEbp))) );
#endif
        LOG( (LF_CORDB, LL_INFO1000, "DT::TASSC:PC:  PC:%x    SP:%x\n",
             (SIZE_T)*(rd->pPC), rd->SP));
            
        rsfd->needChainRegisters = true;

        //
        // Bump our pointers to the next space for the next frame.
        //
        pEvent->StackTraceResultData.traceCount++;
        rsfd->currentSTRData++;
        rsfd->eventSize += sizeof(DebuggerIPCE_STRData);
    }

    return SWA_CONTINUE;
}
Ejemplo n.º 12
0
void GetVAInfo(bool *pfVarArgs,
               void **ppSig,
               SIZE_T *pcbSig,
               void **ppFirstArg,
               MethodDesc *pMD,
               REGDISPLAY *rd,
               SIZE_T relOffset)
{
    PCCOR_SIGNATURE sig = pMD->GetSig();
    ULONG callConv = CorSigUncompressCallingConv(sig);

    if ( (callConv & IMAGE_CEE_CS_CALLCONV_MASK)&
         IMAGE_CEE_CS_CALLCONV_VARARG)
    {
        LOG((LF_CORDB,LL_INFO100000, "GVAI: %s::%s is a varargs fnx!\n",
             pMD->m_pszDebugClassName,pMD->m_pszDebugMethodName));

#if defined(_X86_) || defined(_PPC_)
        HRESULT hr = S_OK;
        ICorJitInfo::NativeVarInfo *pNativeInfo;
        // This is a VARARGs function, so pass over the instance-specific
        // info.
        DebuggerJitInfo *dji=g_pDebugger->GetJitInfo(pMD,(BYTE*)(*(rd->pPC)));

        if (dji != NULL)
        {
            hr = FindNativeInfoInILVariableArray((unsigned)ICorDebugInfo::VARARGS_HANDLE,
                                                 relOffset,
                                                 &pNativeInfo,
                                                 dji->m_varNativeInfoCount,
                                                 dji->m_varNativeInfo);
        }

        if (dji == NULL || FAILED(hr) || pNativeInfo==NULL)
        {
#ifdef _DEBUG
            if (dji == NULL)
                LOG((LF_CORDB, LL_INFO1000, "GVAI: varargs? no DJI\n"));
            else if (CORDBG_E_IL_VAR_NOT_AVAILABLE==hr)
                LOG((LF_CORDB, LL_INFO1000, "GVAI: varargs? No VARARGS_HANDLE "
                    "found!\n"));
            else if (pNativeInfo == NULL)
                LOG((LF_CORDB, LL_INFO1000, "GVAI: varargs? No native info\n"));
            else
            {
                _ASSERTE(FAILED(hr));
                LOG((LF_CORDB, LL_INFO1000, "GVAI: varargs? Failed with "
                    "hr:0x%x\n", hr));
            }
#endif //_DEBUG

            // Is this ever bad....
            (*pfVarArgs) = true;
            (*ppSig) = NULL;
            (*pcbSig) = 0;
            (*ppFirstArg) = NULL;
            return;
        }

        BYTE *pvStart = GetPtrFromValue(pNativeInfo, rd);
        VASigCookie *vasc = *(VASigCookie**)pvStart; 
        PCCOR_SIGNATURE sigStart = vasc->mdVASig;
        PCCOR_SIGNATURE sigEnd = sigStart;
        ULONG cArg;
        ULONG iArg;

        sigEnd += _skipMethodSignatureHeader(sigEnd, &cArg);
        for(iArg = 0; iArg< cArg; iArg++)
        {
            sigEnd += _skipTypeInSignature(sigEnd);
        }
        
        (*pfVarArgs) = true;
        (*ppSig) = (void *)vasc->mdVASig;
        (*pcbSig) = sigEnd - sigStart;

        // Note: the first arg is relative to the start of the VASigCookie
        // on the stack

#if !(defined(STACK_GROWS_DOWN_ON_ARGS_WALK)^defined(STACK_GROWS_UP_ON_ARGS_WALK))
#error One and only one between STACK_GROWS_DOWN_ON_ARGS_WALK and STACK_GROWS_UP_ON_ARGS_WALK must be defined!
#endif

#ifdef STACK_GROWS_DOWN_ON_ARGS_WALK
        (*ppFirstArg) = (void *)(pvStart - sizeof(void *) + vasc->sizeOfArgs);
#else
        // Skip the cookie
        (*ppFirstArg) = (void *)(pvStart + sizeof(VASigCookie*));
#endif

        LOG((LF_CORDB,LL_INFO10000, "GVAI: Base Ptr for args is 0x%x\n", 
            (*ppFirstArg)));
#else
        PORTABILITY_ASSERT("GetVAInfo is not implemented on this platform.");
#endif
    }
    else
    {
        LOG((LF_CORDB,LL_INFO100000, "GVAI: %s::%s NOT VarArg!\n",
             pMD->m_pszDebugClassName,pMD->m_pszDebugMethodName));
        
        (*pfVarArgs) = false;

        // So that on the right side we don't wrongly init CordbJITILFrame
        (*ppFirstArg) = (void *)0;
        (*ppSig) = (void *)0;
        (*pcbSig) = (SIZE_T)0;
    }
}
Ejemplo n.º 13
0
 void ProfileTailcallNaked(FunctionIDOrClientID functionIDOrClientID)
 {
     PORTABILITY_ASSERT("Implement for PAL");
 }