Exemplo n.º 1
0
// Find the code manager containing the given address, which might be a return address from a managed function. The
// address may be to another managed function, or it may be to an unmanaged function, or it may be to a GC
// hijack. The address may also refer to an EEType if we've been called from RhpGetClasslibFunction. If it is
// a GC hijack, we will recognize that and use the real return address.
static ICodeManager * FindCodeManagerRespectingReturnAddressHijacks(void * address)
{
    RuntimeInstance * pRI = GetRuntimeInstance();

    // Try looking up the code manager assuming the address is for code first. This is expected to be most common.
    ICodeManager * pCodeManager = pRI->FindCodeManagerByAddress(address);
    if (pCodeManager != NULL)
        return pCodeManager;

    // @TODO: CORERT: Do we need to make this work for CoreRT?
    // Less common, we will look for the address in any of the sections of the module.  This is slower, but is 
    // necessary for EEType pointers and jump stubs.
    Module * pModule = pRI->FindModuleByAddress(address);
    if (pModule != NULL)
        return pModule;

    // Corner-case: The thread might be hijacked -- @TODO: this is a bit brittle because there is no validation that
    // the hijacked return address from the thread is actually related to place where the caller got the hijack 
    // target.
    Thread * pCurThread = ThreadStore::GetCurrentThread();
    if (pCurThread->IsHijacked() && Thread::IsHijackTarget(address))
    {
        ICodeManager * pCodeManagerForHijack = pRI->FindCodeManagerByAddress(pCurThread->GetHijackedReturnAddress());
        ASSERT_MSG(pCodeManagerForHijack != NULL, "expected to find the module for a hijacked return address");
        return pCodeManagerForHijack;
    }

    return NULL;
}
Exemplo n.º 2
0
// Find the module containing the given address, which is a return address from a managed function. The
// address may be to another managed function, or it may be to an unmanaged function, or it may be to a GC
// hijack. The address may also refer to an EEType if we've been called from RhpGetClasslibFunction. If it is
// a GC hijack, we will recgonize that and use the real return address, updating the address passed in.
static Module * FindModuleRespectingReturnAddressHijacks(void ** pAddress)
{
    RuntimeInstance * pRI = GetRuntimeInstance();

    // Try looking up the module assuming the address is for code first. Fall back to a read-only data looukp
    // if that fails. If we have data indicating that the data case is more common then we can reverse the
    // order of checks. Finally check read/write data: generic EETypes live there since they need to be fixed
    // up at runtime to support unification.
    Module * pModule = pRI->FindModuleByCodeAddress(*pAddress);
    if (pModule == NULL)
    {
        pModule = pRI->FindModuleByReadOnlyDataAddress(*pAddress);

        if (pModule == NULL)
            pModule = pRI->FindModuleByDataAddress(*pAddress);

        if (pModule == NULL)
        {
            // Hmmm... we didn't find a managed module for the given PC. We have a return address in unmanaged
            // code, but it could be because the thread is hijacked for GC suspension. If it is then we should
            // get the real return address and try again.
            Thread * pCurThread = ThreadStore::GetCurrentThread();
        
            if (!pCurThread->IsHijacked())
            {
                // The PC isn't in a managed module, and there is no hijack in place, so we have no EH info.
                return NULL;
            }

            // Update the PC passed in to reflect the correct return address.
            *pAddress = pCurThread->GetHijackedReturnAddress();

            pModule = pRI->FindModuleByCodeAddress(*pAddress);
        }
    }

    return pModule;
}