diff options
author | David Wrighton <davidwr@microsoft.com> | 2017-02-15 02:35:19 +0300 |
---|---|---|
committer | David Wrighton <davidwr@microsoft.com> | 2017-02-15 02:35:19 +0300 |
commit | 720e17f599c1d8aca941dbca8a9492f3474f3b05 (patch) | |
tree | 544ecb53dbff7736b2945c7b58c5b6f997ee4734 /src/Native/Runtime/MiscHelpers.cpp | |
parent | 1a8e729b2e9e3915947cace8c3bf316237d519e6 (diff) |
Refactor use of TypeManager and Module pointers within the BCL
- Move from using an IntPtr which may represent a TypeManager* or a OS module pointer to using a struct TypeManagerHandle consistently
- Except for RuntimeSignature, which has a third possible meaning of its IntPtr. That work will be done in a seperate change, and wil result in removal of nearly all of the new TypeManagerHandle calls in this delta.
- This struct contains a bit which indicates which form of pointer is being worked with, as well as routines for performing RVA access as appropriate
- Added new api to redhawk to get the OS module list (Used in crash dump generation)
- Added new api to get the OS module of of a pointer. These are not yet enabled for TypeManager based scenarios, but that will be done in a followon change. Eventually these will exclusively be use for instruction pointers, and will tie into diagnostic scenarios around stack traces, etc. Currently, it is also used in a few reflection scenarios. Those code patterns will be removed soon.
- Similarly distinguished between getting the OS module for an EEType, and getting the module for an EEType. This is used in error message scenarios.
- Update RhFindBlob to work with both types of module pointers
[tfs-changeset: 1647831]
Diffstat (limited to 'src/Native/Runtime/MiscHelpers.cpp')
-rw-r--r-- | src/Native/Runtime/MiscHelpers.cpp | 188 |
1 files changed, 144 insertions, 44 deletions
diff --git a/src/Native/Runtime/MiscHelpers.cpp b/src/Native/Runtime/MiscHelpers.cpp index 17153dfaa..b1e0958dc 100644 --- a/src/Native/Runtime/MiscHelpers.cpp +++ b/src/Native/Runtime/MiscHelpers.cpp @@ -75,7 +75,7 @@ COOP_PINVOKE_HELPER(DispatchMap*, RhGetDispatchMapForType, (EEType * pEEType)) // modules are available based on the return count. It is also possible to call this method without an array, // in which case just the module count is returned (note that it's still possible for the module count to // increase between calls to this method). -COOP_PINVOKE_HELPER(UInt32, RhGetLoadedModules, (Array * pResultArray)) +COOP_PINVOKE_HELPER(UInt32, RhGetLoadedOSModules, (Array * pResultArray)) { // Note that we depend on the fact that this is a COOP helper to make writing into an unpinned array safe. @@ -99,11 +99,69 @@ COOP_PINVOKE_HELPER(UInt32, RhGetLoadedModules, (Array * pResultArray)) } END_FOREACH_MODULE + ReaderWriterLock::ReadHolder read(&GetRuntimeInstance()->GetTypeManagerLock()); + + RuntimeInstance::OsModuleList osModules = GetRuntimeInstance()->GetOsModuleList(); + + for (RuntimeInstance::OsModuleList::Iterator iter = osModules.Begin(); iter != osModules.End(); iter++) + { + if (pResultArray && (cModules < cResultArrayElements)) + pResultElements[cModules] = iter->m_osModule; + cModules++; + } + return cModules; } -COOP_PINVOKE_HELPER(HANDLE, RhGetModuleFromPointer, (PTR_VOID pPointerVal)) +// Get the list of currently loaded Redhawk modules (as OS HMODULE handles or TypeManager pointers as appropriate). +// The caller provides a reference +// to an array of pointer-sized elements and we return the total number of modules currently loaded (whether +// that is less than, equal to or greater than the number of elements in the array). If there are more modules +// loaded than the array will hold then the array is filled to capacity and the caller can tell further +// modules are available based on the return count. It is also possible to call this method without an array, +// in which case just the module count is returned (note that it's still possible for the module count to +// increase between calls to this method). +COOP_PINVOKE_HELPER(UInt32, RhGetLoadedModules, (Array * pResultArray)) { + // Note that we depend on the fact that this is a COOP helper to make writing into an unpinned array safe. + + // If a result array is passed then it should be an array type with pointer-sized components that are not + // GC-references. + ASSERT(!pResultArray || pResultArray->get_EEType()->IsArray()); + ASSERT(!pResultArray || !pResultArray->get_EEType()->HasReferenceFields()); + ASSERT(!pResultArray || pResultArray->get_EEType()->get_ComponentSize() == sizeof(void*)); + + UInt32 cResultArrayElements = pResultArray ? pResultArray->GetArrayLength() : 0; + TypeManagerHandle * pResultElements = pResultArray ? (TypeManagerHandle*)(pResultArray + 1) : NULL; + + UInt32 cModules = 0; + + FOREACH_MODULE(pModule) + { + if (pResultArray && (cModules < cResultArrayElements)) + pResultElements[cModules] = TypeManagerHandle::Create(pModule->GetOsModuleHandle()); + + cModules++; + } + END_FOREACH_MODULE + + ReaderWriterLock::ReadHolder read(&GetRuntimeInstance()->GetTypeManagerLock()); + + RuntimeInstance::TypeManagerList typeManagers = GetRuntimeInstance()->GetTypeManagerList(); + + for (RuntimeInstance::TypeManagerList::Iterator iter = typeManagers.Begin(); iter != typeManagers.End(); iter++) + { + if (pResultArray && (cModules < cResultArrayElements)) + pResultElements[cModules] = TypeManagerHandle::Create(iter->m_pTypeManager); + cModules++; + } + + return cModules; +} + +COOP_PINVOKE_HELPER(HANDLE, RhGetOSModuleFromPointer, (PTR_VOID pPointerVal)) +{ + // TODO, this will always return nullptr in TypeManager based systems. Module * pModule = GetRuntimeInstance()->FindModuleByAddress(pPointerVal); if (pModule != NULL) @@ -112,14 +170,14 @@ COOP_PINVOKE_HELPER(HANDLE, RhGetModuleFromPointer, (PTR_VOID pPointerVal)) return NULL; } -COOP_PINVOKE_HELPER(HANDLE, RhGetModuleFromEEType, (EEType * pEEType)) +COOP_PINVOKE_HELPER(HANDLE, RhGetOSModuleFromEEType, (EEType * pEEType)) { #if CORERT - return (HANDLE)(pEEType->GetTypeManager()); + return pEEType->GetTypeManagerPtr()->AsTypeManager()->GetOsModuleHandle(); #else #if EETYPE_TYPE_MANAGER if (pEEType->HasTypeManager()) - return (HANDLE)(pEEType->GetTypeManager()); + return pEEType->GetTypeManagerPtr()->AsTypeManager()->GetOsModuleHandle(); #endif // For dynamically created types, return the module handle that contains the template type @@ -142,65 +200,107 @@ COOP_PINVOKE_HELPER(HANDLE, RhGetModuleFromEEType, (EEType * pEEType)) #endif // !CORERT } -COOP_PINVOKE_HELPER(Boolean, RhFindBlob, (HANDLE hOsModule, UInt32 blobId, UInt8 ** ppbBlob, UInt32 * pcbBlob)) +COOP_PINVOKE_HELPER(TypeManagerHandle, RhGetModuleFromEEType, (EEType * pEEType)) { #if CORERT - ReadyToRunSectionType section = - (ReadyToRunSectionType)((UInt32)ReadyToRunSectionType::ReadonlyBlobRegionStart + blobId); - ASSERT(section <= ReadyToRunSectionType::ReadonlyBlobRegionEnd); - - TypeManager* pModule = (TypeManager*)hOsModule; + return *pEEType->GetTypeManagerPtr(); +#else +#if EETYPE_TYPE_MANAGER + if (pEEType->HasTypeManager()) + return *pEEType->GetTypeManagerPtr(); +#endif - int length; - void* pBlob; - pBlob = pModule->GetModuleSection(section, &length); + // For dynamically created types, return the module handle that contains the template type + if (pEEType->IsDynamicType()) + pEEType = pEEType->get_DynamicTemplateType(); - *ppbBlob = (UInt8*)pBlob; - *pcbBlob = (UInt32)length; + if (pEEType->get_DynamicModule() != nullptr) + { + // We should never get here (an EEType not located in any module) so fail fast to indicate the bug. + RhFailFast(); + return TypeManagerHandle::Null(); + } - return pBlob != NULL; -#else - // Search for the Redhawk module contained by the OS module. FOREACH_MODULE(pModule) { - if (pModule->GetOsModuleHandle() == hOsModule) - { - // Found a module match. Look through the blobs for one with a matching ID. - UInt32 cbBlobs; - BlobHeader * pBlob = pModule->GetReadOnlyBlobs(&cbBlobs); + if (pModule->ContainsReadOnlyDataAddress(pEEType) || pModule->ContainsDataAddress(pEEType)) + return TypeManagerHandle::Create(pModule->GetOsModuleHandle()); + } + END_FOREACH_MODULE - while (cbBlobs) + // We should never get here (an EEType not located in any module) so fail fast to indicate the bug. + RhFailFast(); + return TypeManagerHandle::Null(); +#endif // !CORERT +} + +COOP_PINVOKE_HELPER(Boolean, RhFindBlob, (TypeManagerHandle *pTypeManagerHandle, UInt32 blobId, UInt8 ** ppbBlob, UInt32 * pcbBlob)) +{ + TypeManagerHandle typeManagerHandle = *pTypeManagerHandle; + + if (typeManagerHandle.IsTypeManager()) + { + ReadyToRunSectionType section = + (ReadyToRunSectionType)((UInt32)ReadyToRunSectionType::ReadonlyBlobRegionStart + blobId); + ASSERT(section <= ReadyToRunSectionType::ReadonlyBlobRegionEnd); + + TypeManager* pModule = typeManagerHandle.AsTypeManager(); + + int length; + void* pBlob; + pBlob = pModule->GetModuleSection(section, &length); + + *ppbBlob = (UInt8*)pBlob; + *pcbBlob = (UInt32)length; + + return pBlob != NULL; + } +#if !CORERT + else + { + HANDLE hOsModule = typeManagerHandle.AsOsModule(); + // Search for the Redhawk module contained by the OS module. + FOREACH_MODULE(pModule) + { + if (pModule->GetOsModuleHandle() == hOsModule) { - UInt32 cbTotalBlob = sizeof(BlobHeader) + pBlob->m_size; - ASSERT(cbBlobs >= cbTotalBlob); + // Found a module match. Look through the blobs for one with a matching ID. + UInt32 cbBlobs; + BlobHeader * pBlob = pModule->GetReadOnlyBlobs(&cbBlobs); - if (pBlob->m_id == blobId) + while (cbBlobs) { - // Found the matching blob, return it. - *ppbBlob = (UInt8*)(pBlob + 1); - *pcbBlob = pBlob->m_size; - return TRUE; + UInt32 cbTotalBlob = sizeof(BlobHeader) + pBlob->m_size; + ASSERT(cbBlobs >= cbTotalBlob); + + if (pBlob->m_id == blobId) + { + // Found the matching blob, return it. + *ppbBlob = (UInt8*)(pBlob + 1); + *pcbBlob = pBlob->m_size; + return TRUE; + } + + cbBlobs -= cbTotalBlob; + pBlob = (BlobHeader*)((UInt8*)pBlob + cbTotalBlob); } - cbBlobs -= cbTotalBlob; - pBlob = (BlobHeader*)((UInt8*)pBlob + cbTotalBlob); + // If we get here then we found a module match but didn't find a blob with a matching ID. That's a + // non-catastrophic error. + *ppbBlob = NULL; + *pcbBlob = 0; + return FALSE; } - - // If we get here then we found a module match but didn't find a blob with a matching ID. That's a - // non-catastrophic error. - *ppbBlob = NULL; - *pcbBlob = 0; - return FALSE; } + END_FOREACH_MODULE } - END_FOREACH_MODULE +#endif // !CORERT // If we get here we were passed a bad module handle and should fail fast since this indicates a nasty bug // (which could lead to the wrong blob being returned in some cases). RhFailFast(); return FALSE; -#endif // !CORERT } // This helper is not called directly but is used by the implementation of RhpCheckCctor to locate the @@ -640,9 +740,9 @@ COOP_PINVOKE_HELPER(Boolean, RhpRegisterFrozenSegment, (void* pSegmentStart, UIn return RedhawkGCInterface::RegisterFrozenSection(pSegmentStart, length) != NULL; } -COOP_PINVOKE_HELPER(void*, RhpGetModuleSection, (TypeManager* pModule, Int32 headerId, Int32* length)) +COOP_PINVOKE_HELPER(void*, RhpGetModuleSection, (TypeManagerHandle pModule, Int32 headerId, Int32* length)) { - return pModule->GetModuleSection((ReadyToRunSectionType)headerId, length); + return pModule.AsTypeManager()->GetModuleSection((ReadyToRunSectionType)headerId, length); } COOP_PINVOKE_HELPER(void, RhGetCurrentThreadStackBounds, (PTR_VOID * ppStackLow, PTR_VOID * ppStackHigh)) |